Skip to content

Commit 59aeb96

Browse files
committed
Integrate GLKH-Solver
1 parent ad788ed commit 59aeb96

35 files changed

+487
-532
lines changed

install/prepare-jenkins-slave.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ sudo apt-get install -y python3-wstool python3-catkin-tools
99
# Package dependencies.
1010
echo "Installing CGAL dependencies."
1111
sudo apt-get install -y libcgal-dev
12-
echo "Installing MONO dependencies."
13-
sudo apt-get install -y mono-devel
12+
sudo apt-get install -y libgmp-dev libmpfr-dev
1413
echo "Installig GLOG dependencices."
1514
sudo apt-get install -y libgoogle-glog-dev

polygon_coverage_planners/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ set(CMAKE_CXX_STANDARD 17)
1111
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
1212
set(CMAKE_BUILD_TYPE Release)
1313

14-
# TODO(rikba): Make catkin package.
15-
find_package(PkgConfig)
16-
pkg_check_modules(MONO mono-2 REQUIRED)
17-
include_directories(${MONO_INCLUDE_DIRS})
1814

1915
catkin_package(
2016
INCLUDE_DIRS include ${catkin_INCLUDE_DIRS}

polygon_coverage_planners/src/graphs/sweep_plan_graph.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include <polygon_coverage_geometry/tcd.h>
3131
#include <polygon_coverage_geometry/visibility_polygon.h>
3232

33-
#include <polygon_coverage_solvers/gk_ma.h>
33+
#include <polygon_coverage_solvers/glkh.h>
3434

3535
#include <CGAL/Boolean_set_operations_2.h>
3636
#include <CGAL/create_offset_polygons_from_polygon_with_holes_2.h>
@@ -522,20 +522,20 @@ bool SweepPlanGraph::solve(const Point_2& start, const Point_2& goal,
522522
const size_t goal_idx = temp_gtsp_graph.size() - 1;
523523
const size_t start_idx = temp_gtsp_graph.size() - 2;
524524

525-
// Solve using GK MA.
525+
// Solve using GLKH.
526526
std::vector<std::vector<int>> m = temp_gtsp_graph.getAdjacencyMatrix();
527527
std::vector<std::vector<int>> clusters;
528528
if (!temp_gtsp_graph.getClusters(&clusters)) {
529529
ROS_ERROR("Cannot get clusters.");
530530
return false;
531531
}
532-
gk_ma::Task task(m, clusters);
533-
gk_ma::GkMa& solver = gk_ma::GkMa::getInstance();
532+
glkh::Task task(m, clusters);
533+
glkh::Glkh& solver = glkh::Glkh::getInstance();
534534
solver.setSolver(task);
535535

536536
ROS_INFO("Start solving GTSP");
537537
if (!solver.solve()) {
538-
ROS_ERROR("GkMa solution failed.");
538+
ROS_ERROR("GLKH solution failed.");
539539
return false;
540540
}
541541
ROS_INFO("Finished solving GTSP");

polygon_coverage_planners/src/planners/polygon_stripmap_planner.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ bool PolygonStripmapPlanner::runSolver(const Point_2& start,
9999
std::vector<Point_2>* solution) const {
100100
ROS_ASSERT(solution);
101101

102-
ROS_INFO("Start solving GTSP using GK MA.");
102+
ROS_INFO("Start solving GTSP using GLKH.");
103103
return sweep_plan_graph_.solve(start, goal, solution);
104104
}
105105

polygon_coverage_solvers/CMakeLists.txt

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,49 +13,18 @@ catkin_package(
1313
)
1414
include_directories(include ${catkin_INCLUDE_DIRS})
1515

16-
# Add mono to invoke gk_ma.
17-
find_package(PkgConfig)
18-
pkg_check_modules(MONO mono-2 REQUIRED)
19-
include_directories(${MONO_INCLUDE_DIRS})
20-
21-
# Download gk_ma
22-
set(GKMA_INCLUDE_DIR ${CMAKE_BINARY_DIR}/gk_ma-prefix/src/gk_ma)
16+
# Download glkh
2317
include(ExternalProject)
2418
ExternalProject_Add(
25-
gk_ma
26-
URL http://www.cs.nott.ac.uk/~pszdk/gtsp_ma_source_codes.zip
27-
URL https://polybox.ethz.ch/index.php/s/H4NXeaNPWo6VBrf/download
28-
DOWNLOAD_NAME gtsp_ma_source_codes.zip
29-
URL_MD5 765fad8e3746fa3dd9b81be0afb34d35
19+
glkh
20+
URL http://webhotel4.ruc.dk/~keld/research/GLKH/GLKH-1.0.tgz
21+
DOWNLOAD_NAME glkh_source_codes.tgz
22+
URL_MD5 9b0ba92053dac798f550c5c8a9524120
23+
BINARY_DIR ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_BIN_DESTINATION}
3024
PATCH_COMMAND
31-
COMMAND patch GkMa/OurHeuristic/Algorithm.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/Algorithm.patch
32-
COMMAND patch NativeHelper/ClusterOptimisation.cpp ${CMAKE_CURRENT_SOURCE_DIR}/patches/ClusterOptimisationCpp.patch
33-
COMMAND patch GkMa/OurHeuristic/Types/Generation.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/Generation.patch
34-
COMMAND patch GkMa/OurHeuristic/GeneticAlgorithm.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/GeneticAlgorithm.patch
35-
COMMAND patch GkMa/Helper.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/Helper.patch
36-
COMMAND patch NativeHelper/ClusterOptimisation.h ${CMAKE_CURRENT_SOURCE_DIR}/patches/ClusterOptimisationH.patch
37-
COMMAND patch NativeHelper/ImprovementManager.h ${CMAKE_CURRENT_SOURCE_DIR}/patches/ImprovementManagerH.patch
38-
COMMAND patch NativeHelper/Insert.cpp ${CMAKE_CURRENT_SOURCE_DIR}/patches/InsertCpp.patch
39-
COMMAND patch NativeHelper/Insert.h ${CMAKE_CURRENT_SOURCE_DIR}/patches/InsertH.patch
40-
COMMAND patch NativeHelper/NativeHelper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/patches/NativeHelperCpp.patch
41-
COMMAND patch NativeHelper/Swap.cpp ${CMAKE_CURRENT_SOURCE_DIR}/patches/SwapCpp.patch
42-
COMMAND patch NativeHelper/NativeHelper.h ${CMAKE_CURRENT_SOURCE_DIR}/patches/NativeHelperH.patch
43-
COMMAND patch GkMa/OurHeuristic/NativeHelper.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/NativeHelper.patch
44-
COMMAND patch GkMa/OurSolver.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/OurSolver.patch
45-
COMMAND patch GkMa/OurHeuristic/Types/Permutation.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/Permutation.patch
46-
COMMAND patch GkMa/Program.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/Program.patch
47-
COMMAND patch GkMa/Solver.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/Solver.patch
48-
COMMAND patch GkMa/Loader/Task.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/Task.patch
49-
COMMAND patch GkMa/OurHeuristic/Types/Tour.cs ${CMAKE_CURRENT_SOURCE_DIR}/patches/Tour.patch
50-
UPDATE_COMMAND ""
51-
CONFIGURE_COMMAND
52-
COMMAND cp ${PROJECT_SOURCE_DIR}/patches/MakefileCpp ./MakefileCpp
53-
COMMAND cp ${PROJECT_SOURCE_DIR}/patches/MakefileCs ./MakefileCs
54-
BUILD_COMMAND
55-
COMMAND $(MAKE) -f MakefileCs BUILD_PATH="${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
56-
COMMAND $(MAKE) -f MakefileCpp BUILD_PATH="${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
57-
INSTALL_COMMAND
58-
COMMAND ${CMAKE_COMMAND} -E create_symlink /usr/lib/libmono-native.so ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/System.Native
25+
COMMAND patch --forward ./SRC/SolveTSP.c < ${PROJECT_SOURCE_DIR}/patches/SolveTSP.patch
26+
COMMAND cp ${PROJECT_SOURCE_DIR}/patches/CMakeLists.txt ./
27+
INSTALL_COMMAND ""
5928
)
6029

6130
# Download GTSP test instances.
@@ -76,20 +45,23 @@ ExternalProject_Add(
7645
# LIBRARIES #
7746
#############
7847
add_library(${PROJECT_NAME}
79-
src/gk_ma.cc
48+
src/glkh.cc
8049
src/combinatorics.cc
8150
src/boolean_lattice.cc
8251
)
83-
target_link_libraries(${PROJECT_NAME} ${MONO_LIBRARIES} ${catkin_LIBRARIES})
52+
53+
target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES})
8454

8555
#########
8656
# TESTS #
8757
#########
88-
catkin_add_gtest(test_combinatorics test/combinatorics-test.cpp)
58+
catkin_add_gtest(test_combinatorics
59+
test/combinatorics-test.cpp
60+
)
8961
target_link_libraries(test_combinatorics ${PROJECT_NAME} ${catkin_LIBRARIES})
9062

91-
catkin_add_gtest(test_gk_ma test/gk_ma-test.cpp)
92-
target_link_libraries(test_gk_ma ${PROJECT_NAME} ${catkin_LIBRARIES})
63+
catkin_add_gtest(test_glkh test/glkh-test.cpp)
64+
target_link_libraries(test_glkh ${PROJECT_NAME} ${catkin_LIBRARIES})
9365

9466

9567
##########

polygon_coverage_solvers/include/polygon_coverage_solvers/gk_ma.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
#include <string>
2424
#include <vector>
2525

26-
#include <mono/metadata/object.h>
27-
2826
// Interfaces with the GK MA GTSP solver.
2927
namespace polygon_coverage_planning {
3028
namespace gk_ma {
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* polygon_coverage_planning implements algorithms for coverage planning in
3+
* general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4+
* Systems Lab, ETH Zürich
5+
*
6+
* This program is free software: you can redistribute it and/or modify it under
7+
* the terms of the GNU General Public License as published by the Free Software
8+
* Foundation, either version 3 of the License, or (at your option) any later
9+
* version.
10+
*
11+
* This program is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14+
* details.
15+
*
16+
* You should have received a copy of the GNU General Public License along with
17+
* this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#ifndef POLYGON_COVERAGE_SOLVERS_GLKH_H_
21+
#define POLYGON_COVERAGE_SOLVERS_GLKH_H_
22+
23+
#include <string>
24+
#include <vector>
25+
26+
// Interfaces with the GLKH GTSP solver.
27+
namespace polygon_coverage_planning {
28+
namespace glkh {
29+
struct Task {
30+
Task(const std::vector<std::vector<int>>& m,
31+
const std::vector<std::vector<int>>& clusters)
32+
: m(m), clusters(clusters) {}
33+
bool mIsSymmetric() const;
34+
bool mIsSquare() const;
35+
std::vector<std::vector<int>> m;
36+
std::vector<std::vector<int>> clusters;
37+
};
38+
39+
// References GLKH. Singleton, because it may only be referenced once during
40+
// runtime.
41+
// https://stackoverflow.com/questions/1008019/c-singleton-design-pattern
42+
class Glkh {
43+
public:
44+
inline static Glkh& getInstance() {
45+
static Glkh instance;
46+
return instance;
47+
}
48+
Glkh(Glkh const&) = delete;
49+
void operator=(Glkh const&) = delete;
50+
51+
void setSolver(const Task& task);
52+
bool solve();
53+
inline std::vector<int> getSolution() const { return solution_; }
54+
55+
private:
56+
Glkh();
57+
~Glkh() = default;
58+
59+
std::vector<int> solution_;
60+
};
61+
} // namespace glkh
62+
} // namespace polygon_coverage_planning
63+
64+
#endif // POLYGON_COVERAGE_SOLVERS_GLKH_H_

polygon_coverage_solvers/include/polygon_coverage_solvers/impl/graph_base_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ GraphBase<NodeProperty, EdgeProperty>::getAdjacencyMatrix() const {
388388
if (edgeExists(edge) && getEdgeCost(edge, &cost)) {
389389
m[i][j] = static_cast<int>(cost * scale);
390390
} else {
391-
m[i][j] = std::numeric_limits<int>::max();
391+
m[i][j] = std::numeric_limits<int>::max(); // TODO: overflow!
392392
}
393393
}
394394
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
3+
#ifndef POLYGON_COVERAGE_SOLVERS_UTILS_H_
4+
#define POLYGON_COVERAGE_SOLVERS_UTILS_H_
5+
6+
#include <string>
7+
#include <algorithm>
8+
#include <cctype>
9+
10+
namespace polygon_coverage_planning {
11+
12+
// trim from start (in place)
13+
static inline void ltrim(std::string &s) {
14+
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
15+
return !std::isspace(ch);
16+
}));
17+
}
18+
19+
// trim from end (in place)
20+
static inline void rtrim(std::string &s) {
21+
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
22+
return !std::isspace(ch);
23+
}).base(), s.end());
24+
}
25+
26+
// trim from both ends (in place)
27+
static inline void trim(std::string &s) {
28+
ltrim(s);
29+
rtrim(s);
30+
}
31+
32+
} // namespace polygon_coverage_planning
33+
34+
#endif // POLYGON_COVERAGE_SOLVERS_UTILS_H_

polygon_coverage_solvers/patches/Algorithm.patch

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)