This file is indexed.

/usr/include/Aria/ariaUtil.h is in libaria-dev 2.8.0+repack-1.2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
/*
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 <string>
// #define _XOPEN_SOURCE 500
#include <list>
#include <map>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <float.h>

#if defined(_WIN32) || defined(WIN32)
#include <sys/timeb.h>
#include <sys/stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <strings.h>
#endif // ifndef win32

#include <time.h>
#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<class T> 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<class T> 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<std::string> &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<const char *> *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<std::string> 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<double> 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 <const std::string&, const std::string&, bool> 
/// 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<ArDaemonizer> 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<Priority, std::string> ourPriorityNames;
  /// Map of displayable text to priorities
  static std::map<std::string, ArPriority::Priority> 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<char *, ArTypes::UByte2> *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<char *, ArTypes::UByte2> *getFunctor(void) { return myFunctor; }
protected:
  std::string myName;
  ArTypes::UByte2 myMaxLength;
  ArFunctor2<char *, ArTypes::UByte2> *myFunctor;
};

/// This class just holds some helper functions for the ArStringInfoHolder 
class ArStringInfoHolderFunctions
{
public:
  static void intWrapper(char * buffer, ArTypes::UByte2 bufferLen, 
			 ArRetFunctor<int> *functor, const char *format)
    { snprintf(buffer, bufferLen - 1, format, functor->invokeR()); 
    buffer[bufferLen-1] = '\0'; }
  static void doubleWrapper(char * buffer, ArTypes::UByte2 bufferLen, 
			    ArRetFunctor<double> *functor, const char *format)
    { snprintf(buffer, bufferLen - 1, format, functor->invokeR()); 
    buffer[bufferLen-1] = '\0'; }
  static void boolWrapper(char * buffer, ArTypes::UByte2 bufferLen, 
			  ArRetFunctor<bool> *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<const char *> *functor, 
			    const char *format)
  { snprintf(buffer, bufferLen - 1, format, functor->invokeR()); 
  buffer[bufferLen-1] = '\0'; }
  static void unsignedLongWrapper(char * buffer, ArTypes::UByte2 bufferLen, 
			 ArRetFunctor<unsigned long> *functor, const char *format)
    { snprintf(buffer, bufferLen - 1, format, functor->invokeR()); 
    buffer[bufferLen-1] = '\0'; }
  static void longWrapper(char * buffer, ArTypes::UByte2 bufferLen, 
			 ArRetFunctor<long> *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<MyClass> * > 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 GenericFunctor> 
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<int, GenericFunctor>(-position, 
					     functor));
      myDataMutex.unlock();
    }
  /// Removes a callback
  void remCallback(GenericFunctor functor)
    {
      myDataMutex.lock();
      typename std::multimap<int, GenericFunctor>::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<int, GenericFunctor> myList;
  bool mySingleShot;
  bool myLogging;
};

/** A class to hold a list of callbacks to call sequentially. 
  @ingroup UtilityClasses
*/
class ArCallbackList : public ArGenericCallbackList<ArFunctor *>
{
public:
  /// Constructor
  ArCallbackList(const char *name = "", 
			  ArLog::LogLevel logLevel = ArLog::Verbose,
			  bool singleShot = false) : 
    ArGenericCallbackList<ArFunctor *>(name, logLevel, singleShot)
    {
    }
  /// Destructor
  virtual ~ArCallbackList()
    {
    }
  /// Calls the callback list
  void invoke(void)
    {
      myDataMutex.lock();
      
      std::multimap<int, ArFunctor *>::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<P1>.
    Declare like this:
    @code
      ArCallbackList1<int> callbackList;
    @endcode
    then add a functor like this:
    @code
      ArFunctor1C<MyClass, int> func;
      ...
      callbackList.addCallback(&func);
    @endcode
    then invoke it like this:
    @code
      callbackList.invoke(23);
    @endcode
    @ingroup UtilityClasses
**/
template<class P1>
class ArCallbackList1 : public ArGenericCallbackList<ArFunctor1<P1> *>
{
public:
  /// Constructor
  ArCallbackList1(const char *name = "", 
			  ArLog::LogLevel logLevel = ArLog::Verbose,
			  bool singleShot = false) : 
    ArGenericCallbackList<ArFunctor1<P1> *>(name, logLevel, singleShot)
    {
    }
  /// Destructor
  virtual ~ArCallbackList1()
    {
    }
  /// Calls the callback list
  void invoke(P1 p1)
    {
      ArGenericCallbackList<ArFunctor1<P1> *>::myDataMutex.lock();
      
      typename std::multimap<int, ArFunctor1<P1> *>::iterator it;
      ArFunctor1<P1> *functor;
      
      if(ArGenericCallbackList<ArFunctor1<P1> *>::myLogging)
	ArLog::log(
		ArGenericCallbackList<ArFunctor1<P1> *>::myLogLevel, 
		"%s: Starting calls1", 
		ArGenericCallbackList<ArFunctor1<P1> *>::myName.c_str());
      
      for (it = ArGenericCallbackList<ArFunctor1<P1> *>::myList.begin(); 
	   it != ArGenericCallbackList<ArFunctor1<P1> *>::myList.end(); 
	   it++)
      {
	functor = (*it).second;
	if (functor == NULL) 
	  continue;
	
	if(ArGenericCallbackList<ArFunctor1<P1> *>::myLogging)
	{
	  if (functor->getName() != NULL && functor->getName()[0] != '\0')
	    ArLog::log(ArGenericCallbackList<ArFunctor1<P1> *>::myLogLevel,
		       "%s: Calling functor '%s' at %d",
		       ArGenericCallbackList<ArFunctor1<P1> *>::myName.c_str(), 
		       functor->getName(), -(*it).first);
	  else
	    ArLog::log(ArGenericCallbackList<ArFunctor1<P1> *>::myLogLevel, 
		       "%s: Calling unnamed functor at %d", 
		       ArGenericCallbackList<ArFunctor1<P1> *>::myName.c_str(), 
		       -(*it).first);
	}
	functor->invoke(p1);
      }
      
      if(ArGenericCallbackList<ArFunctor1<P1> *>::myLogging)
	ArLog::log(ArGenericCallbackList<ArFunctor1<P1> *>::myLogLevel, "%s: Ended calls", ArGenericCallbackList<ArFunctor1<P1> *>::myName.c_str());
      
      if (ArGenericCallbackList<ArFunctor1<P1> *>::mySingleShot)
      {
	if(ArGenericCallbackList<ArFunctor1<P1> *>::myLogging)
	  ArLog::log(ArGenericCallbackList<ArFunctor1<P1> *>::myLogLevel, 
		     "%s: Clearing callbacks", 
		     ArGenericCallbackList<ArFunctor1<P1> *>::myName.c_str());
	ArGenericCallbackList<ArFunctor1<P1> *>::myList.clear();
      }
      ArGenericCallbackList<ArFunctor1<P1> *>::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<ArLaser *, int, const char *> *getCreateLMS2xxCB(void);
  /// Creates an ArUrg
  static ArLaser *createUrg(int laserNumber, const char *logPrefix);
  /// Gets functor for creating an ArUrg
  static ArRetFunctor2<ArLaser *, int, const char *> *getCreateUrgCB(void);
  /// Creates an ArLMS1XX
  static ArLaser *createLMS1XX(int laserNumber, const char *logPrefix);
  /// Gets functor for creating an ArLMS1XX
  static ArRetFunctor2<ArLaser *, int, const char *> *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<ArLaser *, int, const char *> *getCreateUrg_2_0CB(void);
  /// Creates an ArS3Series
  static ArLaser *createS3Series(int laserNumber, const char *logPrefix);
  /// Gets functor for creating an ArS3Series
  static ArRetFunctor2<ArLaser *, int, const char *> *getCreateS3SeriesCB(void);
  /// Creates an ArLMS5XX
  static ArLaser *createLMS5XX(int laserNumber, const char *logPrefix);
  /// Gets functor for creating an ArLMS5XX
  static ArRetFunctor2<ArLaser *, int, const char *> *getCreateLMS5XXCB(void);
  /// Creates an ArTiM3XX
  static ArLaser *createTiM3XX(int laserNumber, const char *logPrefix);
  /// Gets functor for creating an ArTiM3XX
  static ArRetFunctor2<ArLaser *, int, const char *> *getCreateTiM3XXCB(void);
  /// Creates an ArSZSeries
  static ArLaser *createSZSeries(int laserNumber, const char *logPrefix);
  /// Gets functor for creating an ArSZSeries
  static ArRetFunctor2<ArLaser *, int, const char *> *getCreateSZSeriesCB(void);

protected:
  static ArGlobalRetFunctor2<ArLaser *, int, const char *> ourLMS2xxCB;
  static ArGlobalRetFunctor2<ArLaser *, int, const char *> ourUrgCB;
  static ArGlobalRetFunctor2<ArLaser *, int, const char *> ourLMS1XXCB;
  static ArGlobalRetFunctor2<ArLaser *, int, const char *> ourUrg_2_0CB;
  static ArGlobalRetFunctor2<ArLaser *, int, const char *> ourS3SeriesCB;
  static ArGlobalRetFunctor2<ArLaser *, int, const char *> ourLMS5XXCB;
  static ArGlobalRetFunctor2<ArLaser *, int, const char *> ourTiM3XXCB;
  static ArGlobalRetFunctor2<ArLaser *, int, const char *> ourSZSeriesCB;
};

/// @internal
class ArBatteryMTXCreatorHelper
{
public:
  /// Creates an ArBatteryMTX
  static ArBatteryMTX *createBatteryMTX(int batteryNumber, const char *logPrefix);
  /// Gets functor for creating an ArBatteryMTX
  static ArRetFunctor2<ArBatteryMTX *, int, const char *> *getCreateBatteryMTXCB(void);

protected:
  static ArGlobalRetFunctor2<ArBatteryMTX *, int, const char *> ourBatteryMTXCB;
};

/// @internal
class ArLCDMTXCreatorHelper
{
public:
  /// Creates an ArLCDMTX
  static ArLCDMTX *createLCDMTX(int lcdNumber, const char *logPrefix);
  /// Gets functor for creating an ArLCDMTX
  static ArRetFunctor2<ArLCDMTX *, int, const char *> *getCreateLCDMTXCB(void);

protected:
  static ArGlobalRetFunctor2<ArLCDMTX *, int, const char *> ourLCDMTXCB;
};

/// @internal
class ArSonarMTXCreatorHelper
{
public:
  /// Creates an ArSonarMTX
  static ArSonarMTX *createSonarMTX(int sonarNumber, const char *logPrefix);
  /// Gets functor for creating an ArSonarMTX
  static ArRetFunctor2<ArSonarMTX *, int, const char *> *getCreateSonarMTXCB(void);

protected:
  static ArGlobalRetFunctor2<ArSonarMTX *, int, const char *> 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<ArDeviceConnection *, const char *, const char *, 
		       const char *> *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<ArDeviceConnection *, const char *, const char *, 
		       const char *> *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<ArDeviceConnection *, const char *, const char *,
		       const char *> *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<ArDeviceConnection *, const char *, const char *, 
			     const char *> ourSerialCB;
  static ArGlobalRetFunctor3<ArDeviceConnection *, const char *, const char *, 
			     const char *> ourTcpCB;
  static ArGlobalRetFunctor3<ArDeviceConnection *, const char *, const char *,
			     const char *> ourSerial422CB;
  static ArLog::LogLevel ourSuccessLogLevel;
};
#endif // SWIG

/// Class for finding robot bounds from the basic measurements
class ArPoseUtil
{
public:
  static std::list<ArPose> findCornersFromRobotBounds(
	  double radius, double widthLeft, double widthRight, 
	  double lengthFront, double lengthRear, bool fastButUnsafe);
  static std::list<ArPose> breakUpDistanceEvenly(ArPose start, ArPose end, 
						 int resolution);
};

#endif // ARIAUTIL_H