Skip to content

Commit cf32165

Browse files
committed
added preliminary multihop solver
+ cmake 3.13 required from now on + added adjacency matrix + in a scan cover, edges can be scanned multiple times
1 parent a09b2f8 commit cf32165

File tree

9 files changed

+408
-53
lines changed

9 files changed

+408
-53
lines changed

CMakeLists.txt

+19-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cmake_minimum_required(VERSION 3.10.0)
1+
cmake_minimum_required(VERSION 3.13.0)
22
project(dmsc-visualizer VERSION 0.1.0)
33

44
set(CMAKE_CXX_STANDARD 17)
@@ -8,18 +8,18 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
88
find_package(glm REQUIRED)
99

1010
# GLFW library
11-
# TODO not found -> local path
1211
find_package(glfw3 REQUIRED)
1312

1413
add_library(dmsc STATIC)
1514
set_target_properties(dmsc PROPERTIES PROJECT_SOURCE_DIR ${PROJECT_SOURCE_DIR})
1615

1716
# Debug flags
1817
if(MSVC)
19-
target_compile_options(dmsc PRIVATE /W4
20-
/wd4458 # declaration of 'identifier' hides class member
21-
/wd4100 # 'identifier' : unreferenced formal parameter
18+
target_compile_options(dmsc PRIVATE /W4
19+
/wd4458 # declaration of 'identifier' hides class member
20+
/wd4100 # 'identifier' : unreferenced formal parameter
2221
)
22+
target_link_options(dmsc PUBLIC /NODEFAULTLIB:MSVCRT)
2323
else()
2424
target_compile_options(dmsc PRIVATE -Wall -Wextra -pedantic)
2525
endif()
@@ -36,19 +36,27 @@ endmacro()
3636

3737
# Examples
3838
OPTION(BUILD_SAMPLES
39-
"If the examples are built as well." ON )
39+
"If the examples are built as well." ON)
4040
if(BUILD_SAMPLES)
4141
add_subdirectory(./examples)
4242
endif()
4343

44-
# imgui source files
45-
set(imgui_files
44+
# external source files
45+
set(external_files
4646
external/imgui/imgui.cpp
4747
external/imgui/imgui_draw.cpp
4848
external/imgui/imgui_widgets.cpp
4949
external/imgui/imgui_tables.cpp
5050
external/imgui/backends/imgui_impl_glfw.cpp
5151
external/imgui/backends/imgui_impl_opengl3.cpp
52+
external/glad/src/glad.c
53+
)
54+
55+
# solver source files
56+
set(solver_files
57+
src/solver.cpp
58+
src/solver/greedy_next.cpp
59+
src/solver/greedy_next_khop.cpp
5260
)
5361

5462
# source files
@@ -57,11 +65,9 @@ target_sources(dmsc
5765
src/visuals.cpp
5866
src/instance.cpp
5967
src/opengl_widgets.cpp
60-
src/opengl_primitives.cpp
61-
src/solver.cpp
62-
src/solver/greedy_next.cpp
63-
external/glad/src/glad.c
64-
${imgui_files}
68+
src/opengl_primitives.cpp
69+
${solver_files}
70+
${external_files}
6571
)
6672

6773
target_include_directories(dmsc

examples/solver.cpp

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
#include <dmsc/instance.hpp>
22
#include <dmsc/solver/greedy_next.hpp>
3+
#include <dmsc/solver/greedy_next_khop.hpp>
34
#include <dmsc/visuals.hpp>
45

56
using dmsc::solver::GreedyNext;
7+
using dmsc::solver::GreedyNextKHop;
68

79
int main() {
810
dmsc::Instance instance;
911

1012
// 1. create satellites
1113
dmsc::StateVector sv; // represents a satellite
14+
sv.initial_true_anomaly = dmsc::rad(90.f);
1215
sv.height_perigee = 200.f;
1316
instance.satellites.push_back(sv); // satellite 0
14-
sv.initial_true_anomaly = dmsc::rad(15.f);
15-
sv.inclination = dmsc::rad(45.f);
17+
sv.inclination = dmsc::rad(50.f);
1618
instance.satellites.push_back(sv); // satellite 1
17-
sv.initial_true_anomaly = dmsc::rad(350.f);
18-
sv.inclination = dmsc::rad(23.f);
19+
sv.inclination = dmsc::rad(25.f);
1920
instance.satellites.push_back(sv); // satellite 2
2021

2122
// 2. schedule communications between satellites
22-
instance.edges.push_back(dmsc::Edge(0, 1)); // communication between sat 0 and sat 1
23-
instance.edges.push_back(dmsc::Edge(0, 2)); // communication between sat 0 and sat 2
24-
instance.edges.push_back(dmsc::Edge(1, 2)); // communication between sat 1 and sat 2
23+
instance.edges.push_back(dmsc::Edge(0, 1)); // communication between sat 0 and sat 1
24+
instance.edges.push_back(dmsc::Edge(0, 2, true)); // communication between sat 0 and sat 2
25+
instance.edges.push_back(dmsc::Edge(1, 2, true)); // communication between sat 1 and sat 2
2526

2627
// 3. solve the instance
27-
GreedyNext solver = GreedyNext(dmsc::PhysicalInstance(instance));
28+
GreedyNextKHop solver = GreedyNextKHop(dmsc::PhysicalInstance(instance), 1);
2829
dmsc::Solution solution = solver.solve();
2930

3031
// 4. visualize solution
31-
visualizeSolution(instance, solution);
32+
dmsc::visualizeSolution(instance, solution);
3233

3334
return 0;
3435
}

include/dmsc/edge.hpp

+11-11
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@ struct EdgeOrientation {
1717
class InterSatelliteLink {
1818
public:
1919
// only defined for circular Orbits!
20-
InterSatelliteLink(const uint32_t& sat_from, const uint32_t& sat_to, const std::vector<Satellite>& satellites,
20+
InterSatelliteLink(const uint32_t& v1_idx, const uint32_t& v2_idx, const std::vector<Satellite>& satellites,
2121
const CentralMass cm, const bool optional = false)
22-
: sat_from(sat_from)
23-
, sat_to(sat_to)
22+
: v1_idx(v1_idx)
23+
, v2_idx(v2_idx)
2424
, cm(cm)
2525
, optional(optional) {
2626

27-
if (sat_from >= satellites.size() || sat_to >= satellites.size()) {
27+
if (v1_idx >= satellites.size() || v2_idx >= satellites.size()) {
2828
printf("There is no such satellite in given vector!\n");
2929
assert(false);
3030
exit(EXIT_FAILURE);
3131
}
3232

33-
v1 = &satellites[sat_from];
34-
v2 = &satellites[sat_to];
33+
v1 = &satellites[v1_idx];
34+
v2 = &satellites[v2_idx];
3535
period = v1->getPeriod();
3636
if (v1->getSemiMajorAxis() != v2->getSemiMajorAxis()) {
3737
period = v1->getPeriod() * v2->getPeriod(); // [sec]
@@ -88,7 +88,7 @@ class InterSatelliteLink {
8888

8989
if (sat2.isValid()) {
9090
angle_sat2 = std::acos(glm::dot(sat2.data, target.sat2.direction)); // [rad]
91-
time_sat2 = sat1.t_begin;
91+
time_sat2 = sat2.t_begin;
9292
} else {
9393
time_sat2 = 0.f; // event is invalid, so assume that sat1 was not part of a communication yet
9494
}
@@ -128,15 +128,15 @@ class InterSatelliteLink {
128128
float getMaxAngle() const { return max_angle; }
129129
const Satellite& getV1() const { return *v1; }
130130
const Satellite& getV2() const { return *v2; }
131-
const uint32_t getFromIdx() const { return sat_from; }
132-
const uint32_t getToIdx() const { return sat_to; }
131+
const uint32_t getV1Idx() const { return v1_idx; }
132+
const uint32_t getV2Idx() const { return v2_idx; }
133133
float getRadiusCentralMass() const { return cm.radius_central_mass; }
134134

135135
private:
136136
const Satellite* v1;
137137
const Satellite* v2;
138-
uint32_t sat_from;
139-
uint32_t sat_to;
138+
uint32_t v1_idx;
139+
uint32_t v2_idx;
140140
float period; // [sec] time until satellite constellations repeat
141141
float max_angle; // [rad] max angle for satellites to see each other
142142
bool optional; // If true, no communication is scheduled for this edge

include/dmsc/instance.hpp

+35-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,33 @@
99

1010
namespace dmsc {
1111

12+
/**
13+
* @brief TODO
14+
*
15+
*/
16+
class AdjacencyMatrix {
17+
public:
18+
struct Item {
19+
uint32_t weight = ~0u;
20+
uint32_t edge_idx = ~0u; // index of isl-object in physical instance
21+
Item() = default;
22+
Item(const uint32_t weight, const uint32_t edge_idx)
23+
: weight(weight)
24+
, edge_idx(edge_idx) {}
25+
};
26+
27+
AdjacencyMatrix() = delete;
28+
AdjacencyMatrix(const size_t size, const Item& default_value = Item());
29+
30+
std::vector<std::vector<Item>> matrix;
31+
32+
void clear();
33+
34+
// GETTER
35+
std::vector<Item> column(const size_t column) const;
36+
std::vector<Item> row(const size_t row) const;
37+
};
38+
1239
// ------------------------------------------------------------------------------------------------
1340

1441
/**
@@ -73,12 +100,18 @@ class PhysicalInstance {
73100
float getRadiusCentralMass() const { return cm.radius_central_mass; }
74101
const std::vector<Satellite>& getSatellites() const { return satellites; }
75102
const std::vector<InterSatelliteLink>& getEdges() const { return edges; }
103+
const AdjacencyMatrix& getAdjacencyMatrix() const { return adjacency_matrix; }
104+
const size_t edgeSize() const { return edges.size(); }
105+
const size_t satelliteSize() const { return satellites.size(); }
76106

77107
private:
78-
CentralMass cm;
79-
enum FileReadingMode { READ_INIT, READ_ORBIT, READ_EDGE }; // order must match blocks in file-format
80108
std::vector<Satellite> satellites;
81109
std::vector<InterSatelliteLink> edges;
110+
CentralMass cm;
111+
AdjacencyMatrix adjacency_matrix = AdjacencyMatrix(0);
112+
enum FileReadingMode { READ_INIT, READ_ORBIT, READ_EDGE }; // order must match blocks in file-format
113+
114+
void buildAdjacencyMatrix();
82115
};
83116

84117
// ------------------------------------------------------------------------------------------------

include/dmsc/solver.hpp

+2-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace dmsc {
1111

12-
using ScanCover = std::map<uint32_t, float>; // when an edge is scanned - time in [sec]
12+
using ScanCover = std::multimap<uint32_t, float>; // when an edge is scanned - time in [sec]
1313

1414
struct Solution {
1515
float computation_time = 0.f; // [sec]
@@ -24,7 +24,7 @@ using EdgeOrder = std::vector<int>;
2424
class Solver {
2525
public:
2626
Solver(const PhysicalInstance& instance)
27-
: instance(PhysicalInstance(instance)) {
27+
: instance(instance) {
2828
createCache();
2929
};
3030

@@ -48,15 +48,6 @@ class Solver {
4848
*/
4949
float nextVisibility(const InterSatelliteLink& edge, const float t0);
5050

51-
/**
52-
* @brief
53-
* @param scan_cover A sorted scan cover.
54-
* @return
55-
*/
56-
EdgeOrder toEdgeOrder(const ScanCover& scan_cover);
57-
58-
ScanCover evaluateEdgeOrder(const EdgeOrder& edge_order);
59-
6051
const PhysicalInstance instance;
6152
const float step_size = 1.0f; // [sec]
6253
std::map<const Satellite*, TimelineEvent<glm::vec3>>
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef DMSC_GreedyNextKHop_H
2+
#define DMSC_GreedyNextKHop_H
3+
4+
#include "../instance.hpp"
5+
#include "../solver.hpp"
6+
7+
namespace dmsc {
8+
namespace solver {
9+
10+
class GreedyNextKHop : public Solver {
11+
public:
12+
/**
13+
* @brief Construct a new GreedyNextKHop solver object.
14+
* @param k number of "extra" satellites - e.g. k=1 allows 3 edges (origin, hop, target)
15+
*/
16+
GreedyNextKHop(const PhysicalInstance& instance, const unsigned int k)
17+
: Solver(instance)
18+
, k(k) {}
19+
20+
Solution solve();
21+
22+
private:
23+
struct Communication; // stores all paths for a scheduled communication and the currently chosen path + progress
24+
using Path = std::vector<uint32_t>;
25+
unsigned int k; // number of hops allowed
26+
27+
/**
28+
* @brief Breadth-first search
29+
* @return first: if true, at least one path was found; second: adjacency matrix
30+
*/
31+
std::pair<bool, AdjacencyMatrix> findPaths(const uint32_t from, const uint32_t to) const;
32+
};
33+
34+
} // namespace solver
35+
} // namespace dmsc
36+
37+
#endif

0 commit comments

Comments
 (0)