├── .cproject
├── .gitignore
├── .nedfolders
├── .oppbuildspec
├── .project
├── .settings
└── org.eclipse.cdt.codan.core.prefs
├── Makefile
├── Makefile.vc
├── README.md
├── simulations
├── package.ned
└── run
├── src
├── AmacadControlMessage.msg
├── AmacadData.h
├── AmacadNetworkLayer.cc
├── AmacadNetworkLayer.h
├── AmacadNetworkLayer.ned
├── AmacadWeightCluster.cc
├── AmacadWeightCluster.h
├── AmacadWeightCluster.ned
├── ClusterAlgorithm.cc
├── ClusterAlgorithm.h
├── ClusterAnalysisScenarioManager.cc
├── ClusterAnalysisScenarioManager.h
├── ClusterAnalysisScenarioManager.ned
├── ClusterDraw.cc
├── ClusterDraw.h
├── ExtendedRmacControlMessage.msg
├── ExtendedRmacNetworkLayer.cc
├── ExtendedRmacNetworkLayer.h
├── ExtendedRmacNetworkLayer.ned
├── HighestDegreeCluster.cc
├── HighestDegreeCluster.h
├── HighestDegreeCluster.ned
├── LSUFCluster.cc
├── LSUFCluster.h
├── LSUFCluster.ned
├── LSUFData.cc
├── LSUFData.h
├── LowestIdCluster.cc
├── LowestIdCluster.h
├── LowestIdCluster.ned
├── Makefile
├── MarcumQ.cc
├── MarcumQ.h
├── MdmacControlMessage.msg
├── MdmacNetworkLayer.cc
├── MdmacNetworkLayer.h
├── MdmacNetworkLayer.ned
├── RMACData.h
├── RmacControlMessage.msg
├── RmacNetworkLayer.cc
├── RmacNetworkLayer.h
├── RmacNetworkLayer.ned
├── RouteSimilarityCluster.cc
├── RouteSimilarityCluster.h
├── RouteSimilarityCluster.ned
└── package.ned
└── tools
├── ClusterAnalysis.py
├── GenerateGrid.py
├── LaneWeight.py
└── OmnetReader.py
/.cproject:
--------------------------------------------------------------------------------
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 |
34 |
35 |
36 |
37 |
41 |
42 |
43 |
44 |
45 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
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 |
98 |
99 |
100 |
101 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
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 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 | *.app
10 | *.build
11 | *.luao
12 |
13 | # Packages #
14 | ############
15 | # it's better to unpack these files and commit the raw source
16 | # git has its own built in compression methods
17 | *.7z
18 | *.dmg
19 | *.gz
20 | *.iso
21 | *.jar
22 | *.rar
23 | *.tar
24 | *.zip
25 |
26 | # Logs and databases #
27 | ######################
28 | *.log
29 | *.sql
30 | *.sqlite
31 |
32 | # OS generated files #
33 | ######################
34 | .DS_Store
35 | .DS_Store?
36 | ._*
37 | .Spotlight-V100
38 | .Trashes
39 | Icon?
40 | ehthumbs.db
41 | Thumbs.db
42 | .unison*
43 |
44 | # folders #
45 | ###########
46 | out
47 |
--------------------------------------------------------------------------------
/.nedfolders:
--------------------------------------------------------------------------------
1 | URAE/ned
2 | simulations
3 | src
4 |
--------------------------------------------------------------------------------
/.oppbuildspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ClusterLib
4 |
5 |
6 | veins-2.0
7 |
8 |
9 |
10 | org.omnetpp.cdt.MakefileBuilder
11 |
12 |
13 |
14 |
15 | org.omnetpp.scave.builder.vectorfileindexer
16 |
17 |
18 |
19 |
20 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
21 | clean,full,incremental,
22 |
23 |
24 | ?name?
25 |
26 |
27 |
28 | org.eclipse.cdt.make.core.append_environment
29 | true
30 |
31 |
32 | org.eclipse.cdt.make.core.autoBuildTarget
33 | all
34 |
35 |
36 | org.eclipse.cdt.make.core.buildArguments
37 | MODE=debug CONFIGNAME=${ConfigName}
38 |
39 |
40 | org.eclipse.cdt.make.core.buildCommand
41 | make
42 |
43 |
44 | org.eclipse.cdt.make.core.buildLocation
45 | ${ProjDirPath}
46 |
47 |
48 | org.eclipse.cdt.make.core.cleanBuildTarget
49 | clean
50 |
51 |
52 | org.eclipse.cdt.make.core.contents
53 | org.eclipse.cdt.make.core.activeConfigSettings
54 |
55 |
56 | org.eclipse.cdt.make.core.enableAutoBuild
57 | false
58 |
59 |
60 | org.eclipse.cdt.make.core.enableCleanBuild
61 | true
62 |
63 |
64 | org.eclipse.cdt.make.core.enableFullBuild
65 | true
66 |
67 |
68 | org.eclipse.cdt.make.core.fullBuildTarget
69 | all
70 |
71 |
72 | org.eclipse.cdt.make.core.stopOnError
73 | true
74 |
75 |
76 | org.eclipse.cdt.make.core.useDefaultBuildCmd
77 | true
78 |
79 |
80 |
81 |
82 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
83 | full,incremental,
84 |
85 |
86 |
87 |
88 |
89 | org.eclipse.cdt.core.cnature
90 | org.eclipse.cdt.core.ccnature
91 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
92 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
93 | org.omnetpp.main.omnetppnature
94 |
95 |
96 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.cdt.codan.core.prefs:
--------------------------------------------------------------------------------
1 | #Wed May 15 15:19:43 EST 2013
2 | eclipse.preferences.version=1
3 | org.eclipse.cdt.codan.checkers.errnoreturn=Warning
4 | org.eclipse.cdt.codan.checkers.errnoreturn.params={implicit\=>false}
5 | org.eclipse.cdt.codan.checkers.errreturnvalue=Error
6 | org.eclipse.cdt.codan.checkers.errreturnvalue.params={}
7 | org.eclipse.cdt.codan.checkers.noreturn=Error
8 | org.eclipse.cdt.codan.checkers.noreturn.params={implicit\=>false}
9 | org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
10 | org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
11 | org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
12 | org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
13 | org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
14 | org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={}
15 | org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
16 | org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={}
17 | org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
18 | org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={no_break_comment\=>"no break",last_case_param\=>true,empty_case_param\=>false}
19 | org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
20 | org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={unknown\=>false,exceptions\=>()}
21 | org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
22 | org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
23 | org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
24 | org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
25 | org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
26 | org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
27 | org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
28 | org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
29 | org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
30 | org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
31 | org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
32 | org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
33 | org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
34 | org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
35 | org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
36 | org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
37 | org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
38 | org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
39 | org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
40 | org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={}
41 | org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
42 | org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
43 | org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
44 | org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
45 | org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
46 | org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
47 | org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
48 | org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={}
49 | org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
50 | org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={}
51 | org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
52 | org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={macro\=>true,exceptions\=>()}
53 | org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
54 | org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={paramNot\=>false}
55 | org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
56 | org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={else\=>false,afterelse\=>false}
57 | org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
58 | org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
59 | org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
60 | org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={macro\=>true}
61 | org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
62 | org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={macro\=>true}
63 | org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
64 | org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={macro\=>true,exceptions\=>("@(\#)","$Id")}
65 | org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
66 | org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
67 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: checkmakefiles
2 | cd src && $(MAKE)
3 |
4 | clean: checkmakefiles
5 | cd src && $(MAKE) clean
6 |
7 | cleanall: checkmakefiles
8 | cd src && $(MAKE) MODE=release clean
9 | cd src && $(MAKE) MODE=debug clean
10 | rm -f src/Makefile
11 |
12 | makefiles:
13 | cd src && opp_makemake -f --deep
14 |
15 | checkmakefiles:
16 | @if [ ! -f src/Makefile ]; then \
17 | echo; \
18 | echo '======================================================================='; \
19 | echo 'src/Makefile does not exist. Please use "make makefiles" to generate it!'; \
20 | echo '======================================================================='; \
21 | echo; \
22 | exit 1; \
23 | fi
24 |
--------------------------------------------------------------------------------
/Makefile.vc:
--------------------------------------------------------------------------------
1 | all: checkmakefiles
2 | cd src && $(MAKE) -f Makefile.vc
3 |
4 | clean: checkmakefiles
5 | cd src && $(MAKE) -f Makefile.vc clean
6 |
7 | cleanall: checkmakefiles
8 | cd src && $(MAKE) -f Makefile.vc MODE=release clean
9 | cd src && $(MAKE) -f Makefile.vc MODE=debug clean
10 |
11 | makefiles:
12 | cd src && call opp_nmakemake -f --deep
13 |
14 | checkmakefiles:
15 | @if not exist src\Makefile.vc ( \
16 | echo. && \
17 | echo ============================================================================ && \
18 | echo src/Makefile.vc does not exist. Please use the following command to generate it: && \
19 | echo nmake -f Makefile.vc makefiles && \
20 | echo ============================================================================ && \
21 | echo. && \
22 | exit 1 )
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ClusterLib
2 | ==========
3 |
4 | Implementations of a selection of clustering algorithms for VANETs, written in C++ for OMNeT++
5 |
6 | Supported clustering algorithms:
7 |
8 | - Modified Distributed Mobility-Aware Clustering (MDMAC), by Wolny et al.
9 | Class name: MdmacNetworkLayer
10 |
11 | - Adaptive Mobility-Aware Clustering Algorithm with Destination (AMACAD), by Morales et al.
12 | Class name: AmacadNetworkLayer
13 |
14 | - Robust Mobility Adaptive Clustering (RMAC), by Goonewardene et al.
15 | Class name: RmacNetworkLayer
16 |
17 | - Channel and Route Aware Clustering (CRAC), by Cooper et al.
18 | Class name: ExtendedRmacNetworkLayer
19 |
20 | MDMAC also implements a number of clustering metrics:
21 |
22 | - Lowest ID; Class name: LowestIdCluster
23 |
24 | - Highest Degree; Class name: HighestDegreeCluster
25 |
26 | - Lane-Sense Utility Function, by Almalag et al.; Class name: LSUFCluster
27 |
28 | - Route Similarity, which counts the consecutive common route links between two nodes, by Cooper et al
29 | Class name: RouteSimilarityCluster
30 |
31 | - Destination Analysis, similar to AMACAD's weight; Class name: AmacadWeightCluster
32 |
33 | To compile these you need OMNeT++ 4.2 or later (http://omnetpp.org/), VEINS 2.0 (http://veins.car2x.org/), and Urban Radio Channel (https://github.com/cscooper/URC).
34 |
35 | Email me at andor734@gmail.com or craigsco@bigpond.net.au if you have questions.
36 |
37 | Publications:
38 |
39 | G. Wolny, “Modified dmac clustering algorithm for vanets,” in Systems
40 | and Networks Communications, 2008. ICSNC ’08. 3rd International
41 | Conference on, 2008, pp. 268–273
42 |
43 | M. Morales, C. seon Hong, and Y. C. Bang, “An adaptable mobility-
44 | aware clustering algorithm in vehicular networks,” in Network Opera-
45 | tions and Management Symposium (APNOMS), 2011 13th Asia-Pacific,
46 | Sept 2011, pp. 1–6.
47 |
48 | M. Morales, E. J. Cho, C. seon Hong, and S. Lee, “An adaptable
49 | mobility-aware clustering algorithm in vehicular networks,” Journal of
50 | Computing Science and Engineering, vol. 6, pp. 227–242, Sept 2012.
51 |
52 | R. Goonewardene, F. Ali, and E. Stipidis, “Robust mobility adaptive
53 | clustering scheme with support for geographic routing for vehicular ad
54 | hoc networks,” IET Intell. Transp. Syst., vol. 3, no. 2, p. 148, 2009.
55 |
56 | C. Cooper , M. Ros, F. Safaei, D. Franklin, M. Abolhasan, "Simulation
57 | of Contrasting Clustering Paradigms under an Experimentally-derived
58 | Channel Model", IEEE Vehicular Technology Conference (VTC2014-Fall),
59 | Vancouver, Canada, 2014
60 |
61 | M. Almalag and M. Weigle, “Using traffic flow for cluster formation in
62 | vehicular ad-hoc networks,” in Local Computer Networks (LCN), 2010
63 | IEEE 35th Conference on, 2010, pp. 631–636.
64 |
65 | C. Cooper and A. Mukunthan, “Urban radio channel,” 2014. [Online].
66 | Available: https://github.com/cscooper/URC
67 |
68 |
69 |
--------------------------------------------------------------------------------
/simulations/package.ned:
--------------------------------------------------------------------------------
1 | package clusterlib.simulations;
2 |
3 | @license(LGPL);
4 |
--------------------------------------------------------------------------------
/simulations/run:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | cd `dirname $0`
3 | ../src/clusterlib -n .:../src $*
4 | # for shared lib, use: opp_run -l ../src/clusterlib -n .:../src $*
5 |
--------------------------------------------------------------------------------
/src/AmacadControlMessage.msg:
--------------------------------------------------------------------------------
1 | //
2 | // This program is free software: you can redistribute it and/or modify
3 | // it under the terms of the GNU Lesser General Public License as published by
4 | // the Free Software Foundation, either version 3 of the License, or
5 | // (at your option) any later version.
6 | //
7 | // This program is distributed in the hope that it will be useful,
8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | // GNU Lesser General Public License for more details.
11 | //
12 | // You should have received a copy of the GNU Lesser General Public License
13 | // along with this program. If not, see http://www.gnu.org/licenses/.
14 | //
15 |
16 | cplusplus {{
17 | #include "NetwPkt_m.h"
18 | #include "AmacadData.h"
19 | }}
20 | packet NetwPkt;
21 |
22 | class noncobject NeighbourEntrySet;
23 | class noncobject NeighbourIdSet;
24 |
25 | //
26 | // Describes the AMACAD cluster control message.
27 | // Extends the NetwPkt, so this can be used to encapsulate
28 | // application layer packets as well.
29 | //
30 | packet AmacadControlMessage extends NetwPkt {
31 |
32 | int nodeId; // Identifier of the neighbour.
33 | double xPosition; // X-Position of the neighbour.
34 | double yPosition; // Y-Position of the neighbour.
35 | double speed; // Speed of the neighbour.
36 | double xDestination; // X-Destination of the neighbour.
37 | double yDestination; // Y-Destination of the neighbour.
38 | bool isClusterHead; // Is this node a CH or CHM?
39 | int clusterHead; // The cluster head of this node.
40 | int neighbourCount; // Number of neighbours this node has.
41 | int clusterSize; // If CH, this is the number of nodes in its cluster.
42 | NeighbourEntrySet clusterTable; // Cluster Member table.
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/AmacadData.h:
--------------------------------------------------------------------------------
1 | //
2 | // This program is free software: you can redistribute it and/or modify
3 | // it under the terms of the GNU Lesser General Public License as published by
4 | // the Free Software Foundation, either version 3 of the License, or
5 | // (at your option) any later version.
6 | //
7 | // This program is distributed in the hope that it will be useful,
8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | // GNU Lesser General Public License for more details.
11 | //
12 | // You should have received a copy of the GNU Lesser General Public License
13 | // along with this program. If not, see http://www.gnu.org/licenses/.
14 | //
15 |
16 | #ifndef AMACADDATA_H_
17 | #define AMACADDATA_H_
18 |
19 | class AmacadNetworkLayer;
20 |
21 | /**
22 | * @brief Contains an entry in the AMACAD neighbour table.
23 | */
24 | struct NeighbourEntry {
25 | unsigned int mId; /**< Identifier of the neighbour. */
26 | LAddress::L3Type mNetworkAddress; /**< The IP address of this neighbour. */
27 | double mPositionX; /**< X Position of this node. */
28 | double mPositionY; /**< Y Position of this node. */
29 | double mSpeed; /**< Speed of the node. */
30 | double mDestinationX; /**< X Destination of the node in euclidean coordinates. */
31 | double mDestinationY; /**< Y Destination of the node in euclidean coordinates. */
32 | int mNeighbourCount; /**< Size of this node's neighbour table. */
33 | int mClusterHead; /**< ID of this node's CH. */
34 | bool mIsClusterHead; /**< Is this node a CH? */
35 | int mClusterSize; /**< Size of this node's cluster, if CH. */
36 | simtime_t mLastHeard; /**< Time since we last heard from this node. */
37 | };
38 |
39 | typedef std::vector NeighbourEntrySet;
40 | typedef NeighbourEntrySet::iterator NeighbourEntrySetIterator;
41 |
42 | typedef std::vector NeighbourIdSet;
43 | typedef NeighbourIdSet::iterator NeighbourIdSetIterator;
44 |
45 | #endif /* #define AMACADDATA_H_ */
46 |
--------------------------------------------------------------------------------
/src/AmacadNetworkLayer.h:
--------------------------------------------------------------------------------
1 | //
2 | // This program is free software: you can redistribute it and/or modify
3 | // it under the terms of the GNU Lesser General Public License as published by
4 | // the Free Software Foundation, either version 3 of the License, or
5 | // (at your option) any later version.
6 | //
7 | // This program is distributed in the hope that it will be useful,
8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | // GNU Lesser General Public License for more details.
11 | //
12 | // You should have received a copy of the GNU Lesser General Public License
13 | // along with this program. If not, see http://www.gnu.org/licenses/.
14 | //
15 |
16 | #ifndef AMACADNETWORKLAYER_H_
17 | #define AMACADNETWORKLAYER_H_
18 |
19 | #include
20 |
21 | #include "ClusterAlgorithm.h"
22 | #include "AmacadControlMessage_m.h"
23 |
24 | class AmacadNetworkLayer: public ClusterAlgorithm {
25 |
26 | public:
27 | AmacadNetworkLayer();
28 | virtual ~AmacadNetworkLayer();
29 |
30 | virtual int GetStateCount();
31 | virtual int GetClusterState();
32 | virtual bool IsClusterHead();
33 | virtual bool IsSubclusterHead();
34 | virtual bool IsHierarchical();
35 | virtual int GetMinimumClusterSize();
36 |
37 | virtual void UpdateMessageString();
38 |
39 | /** @brief Initialization of the module and some variables*/
40 | virtual void initialize(int);
41 |
42 | /** @brief Cleanup*/
43 | virtual void finish();
44 |
45 | protected:
46 |
47 | enum ClusterMessageKinds {
48 | AFFILIATION_MESSAGE = LAST_BASE_NETW_MESSAGE_KIND+1, /**< Message for unclustered nodes to find CHs. */
49 | AFFILIATION_ACK_MESSAGE, /**< Affiliation ACK message. */
50 | HELLO_MESSAGE, /**< Inquiry frame. */
51 | HELLO_ACK_MESSAGE, /**< Inquiry response. */
52 | ADD_MESSAGE, /**< Request to join a cluster. */
53 | MEMBER_ACK_MESSAGE, /**< Response to allow a member to join a cluster. */
54 | CLUSTERHEAD_ACK_MESSAGE, /**< Response requiring a new member to become a CH. */
55 | MEMBER_UPDATE_MESSAGE, /**< Tell cluster members to change to a new CH. */
56 | DELETE_MESSAGE, /**< A CM has left the cluster. */
57 | WARNING_MESSAGE, /**< Message warning a CH of a significant change in speed or bandwidth. */
58 | RECLUSTERING_MESSAGE, /**< Message to trigger a reclustering process. */
59 | RECLUSTERING_ACK_MESSAGE, /**< Response to the reclustering message. */
60 | DATA /**< Data packet. */
61 | };
62 |
63 | enum ClusterState {
64 | Unclustered = 0, /**< Initial state. Send out an affiliation message. */
65 | //NeighbourDiscovery, /**< We've declared ourselves a CH, and start looking for our neighbours. */
66 | Joining, /**< We've found a suitable CH, and are trying to join it. */
67 | ClusterMember, /**< We're a CM. */
68 | ClusterHead, /**< We're a CH. */
69 | Reclustering /**< We're in the middle of a reclustering process. */
70 | };
71 |
72 | struct DestinationEntry {
73 | double mTime; /**< The time until which this is our destination. */
74 | Coord mDestination; /**< The coordinates of this destination. */
75 | };
76 |
77 | typedef std::vector DestinationSet;
78 |
79 | struct Neighbour {
80 |
81 | int mId; /**< ID of the node. */
82 | LAddress::L3Type mNetworkAddress; /**< The IP address of this neighbour. */
83 | Coord mPosition; /**< Position of this node. */
84 | double mSpeed; /**< Speed of the node. */
85 | Coord mDestination; /**< Destination of the node in euclidean coordinates. */
86 | double mValueF; /**< Fvz calculated for this node. */
87 | int mNeighbourCount; /**< Size of this node's neighbour table. */
88 | int mClusterHead; /**< ID of this node's CH. */
89 | bool mIsClusterHead; /**< Is this node a CH? */
90 | int mClusterSize; /**< Size of this node's cluster, if CH. */
91 |
92 | simtime_t mLastHeard; /**< Time since we last heard from this node. */
93 |
94 | };
95 |
96 | typedef std::map NeighbourSet;
97 | typedef std::map::iterator NeighbourIterator;
98 |
99 | bool mInitialised;
100 |
101 | //int mId; /**< ID of this node. */
102 | bool mIsClusterHead; /**< Is this node a CH? */
103 | NeighbourSet mNeighbours; /**< This node's neighbour table. */
104 | ClusterState mCurrentState; /**< State of the algorithm. */
105 | NodeIdList mClusterHeadNeighbours; /**< Set of neighbours near CH. */
106 | int mWarningMessageCount; /**< Number of warning messages. */
107 |
108 | double mWeights[3]; /**< Set of weights. */
109 | Coord mCurrentDestination; /**< Current destination. */
110 | DestinationSet mDestinationSet; /**< Set of destinations. */
111 |
112 | double mLastSpeed; /**< Last speed we calculated between our neighbours. */
113 | double mLastBandwidth; /**< Last bandwidth we calculated between our neighbours. */
114 |
115 | int mCurrentClusterHeadTarget; /**< The CH we're currently trying to affiliate with. */
116 |
117 | /**
118 | * @name Handlers
119 | * @brief OMNeT++ message handler.
120 | *
121 | * These methods handle messages passed to this module.
122 | *
123 | **/
124 | /*@{*/
125 |
126 | /** @brief Handle messages from upper layer */
127 | virtual void handleUpperMsg(cMessage* msg);
128 |
129 | /** @brief Handle messages from lower layer */
130 | virtual void handleLowerMsg(cMessage* msg);
131 |
132 | /** @brief Handle self messages */
133 | virtual void handleSelfMsg(cMessage* msg);
134 |
135 | /** @brief decapsulate higher layer message from RmacControlMessage */
136 | virtual cMessage* decapsMsg(AmacadControlMessage*);
137 |
138 | /** @brief Encapsulate higher layer packet into a RmacControlMessage */
139 | virtual NetwPkt* encapsMsg(cPacket*);
140 |
141 | /*@}*/
142 |
143 |
144 | /**
145 | * Process the algorithm state machine.
146 | */
147 | void Process( cMessage *msg = NULL );
148 |
149 |
150 |
151 | /**
152 | * @brief Send a control message
153 | */
154 | void SendControlMessage( int type, int destID = -1 );
155 |
156 |
157 |
158 | /**
159 | * Update neighbour data with the given message.
160 | */
161 | void UpdateNeighbour( AmacadControlMessage *m );
162 |
163 |
164 | /**
165 | * Collect CH neighbours.
166 | */
167 | void CollectClusterHeadNeighbours();
168 |
169 |
170 | /**
171 | * Calculate the F value.
172 | */
173 | double CalculateF( int id=-1 );
174 |
175 |
176 | /**
177 | * Compute neighbour scores and return the ID of the best scoring one.
178 | */
179 | int ComputeNeighbourScores();
180 |
181 |
182 | /**
183 | * Change the CH.
184 | */
185 | void ChangeCH( int ch = -1 );
186 |
187 |
188 | /**
189 | * Get the destination from the destination file.
190 | */
191 | void GetDestinationList();
192 |
193 |
194 | /**
195 | * @name Messages
196 | * @brief Messages this module sends itself.
197 | *
198 | * These are used for timed events.
199 | *
200 | **/
201 | /*@{*/
202 |
203 | cMessage *mStartMessage; /**< Message to start processing. */
204 | cMessage *mAffiliationTimeoutMessage; /**< Timeout for affiliation acknowledgements. */
205 | cMessage *mJoinTimeoutMessage; /**< Timeout for JOIN acknowledgements. */
206 | cMessage *mInquiryTimeoutMessage; /**< Timeout for inquiry period. */
207 | cMessage *mUpdateMobilityMessage; /**< Signal to perform the reclustering. */
208 | cMessage *mChangeDestinationMessage; /**< Signal to change the destination. */
209 |
210 | /*@}*/
211 |
212 |
213 | /**
214 | * @name Parameters
215 | * @brief Module parameters.
216 | *
217 | * These are uses to configure the algorithm.
218 | *
219 | **/
220 | /*@{*/
221 |
222 | int mMinimumDensity; /**< Minimum cluster size before reclustering. */
223 | int mMaximumDensity; /**< Maximum cluster size permissible. */
224 | int mMaximumClusterDensity; /**< Largest number of clusters in the neighbourhood. */
225 | int mMaximumWarningCount; /**< Largest number of warning messages before changing CH. */
226 | double mSpeedThreshold; /**< Speed difference threshold. */
227 | double mBandwidthThreshold; /**< Bandwidth difference threshold. */
228 | simtime_t mTimeDifference; /**< Time to wait between poll checking. */
229 | simtime_t mTimeToLive; /**< Maximum lifetime of a neighbour table entry before it is considered dead. */
230 | simtime_t mTimeoutPeriod; /**< Period of acknowledgement timeout. */
231 |
232 | /*@}*/
233 |
234 | };
235 |
236 | #endif /* AMACADNETWORKLAYER_H_ */
237 |
--------------------------------------------------------------------------------
/src/AmacadNetworkLayer.ned:
--------------------------------------------------------------------------------
1 | //
2 | // This program is free software: you can redistribute it and/or modify
3 | // it under the terms of the GNU Lesser General Public License as published by
4 | // the Free Software Foundation, either version 3 of the License, or
5 | // (at your option) any later version.
6 | //
7 | // This program is distributed in the hope that it will be useful,
8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | // GNU Lesser General Public License for more details.
11 | //
12 | // You should have received a copy of the GNU Lesser General Public License
13 | // along with this program. If not, see http://www.gnu.org/licenses/.
14 | //
15 |
16 | package clusterlib;
17 |
18 | import org.mixim.base.modules.BaseNetwLayer;
19 |
20 | //
21 | // This module implements the clustering mechanism for
22 | // AMACAD.
23 | //
24 | simple AmacadNetworkLayer extends BaseNetwLayer
25 | {
26 | parameters:
27 | @class(AmacadNetworkLayer);
28 |
29 | int minimumDensity;
30 | int maximumDensity;
31 | int maximumClusterDensity;
32 | int maximumWarningCount;
33 | double speedThreshold @unit("mps");
34 | double bandwidthThreshold;
35 | double timeDifference @unit("s");
36 | double timeToLive @unit("s");
37 | double timeoutPeriod @unit("s");
38 |
39 | double distanceWeight;
40 | double speedWeight;
41 | double destinationWeight;
42 |
43 | string destinationFile;
44 |
45 | // signals
46 | @signal[sigOverhead](type="int");
47 | @signal[sigHelloOverhead](type="int");
48 | @signal[sigClusterLifetime](type="double");
49 | @signal[sigClusterSize](type="int");
50 | @signal[sigHeadChange](type="int");
51 | @signal[sigDeathType](type="int");
52 | @signal[sigDeathX](type="double");
53 | @signal[sigDeathY](type="double");
54 | @signal[sigClusterDepth](type="int");
55 |
56 | // statistics
57 | @statistic[ overhead]( source = sigOverhead; record = stats; title = "Overhead per node"; unit = "bytes" );
58 | @statistic[ helloOverhead]( source = sigHelloOverhead; record = stats; title = "Overhead per node (HELLO messages)"; unit = "bytes" );
59 | @statistic[clusterLifetime]( source = sigClusterLifetime; record = stats; title = "Cluster Lifetime"; unit = "s" );
60 | @statistic[ clusterSize]( source = sigClusterSize; record = stats; title = "Cluster Size"; );
61 | @statistic[ headChange]( source = "count(sigHeadChange)"; record = last; title = "CH changes"; );
62 | @statistic[ deathType]( source = sigDeathType; record = vector; title = "Cluster Death Types"; );
63 | @statistic[ deathX]( source = sigDeathX; record = vector; title = "Cluster Death Position X"; );
64 | @statistic[ deathY]( source = sigDeathY; record = vector; title = "Cluster Death Position Y"; );
65 | @statistic[ clusterDepth]( source = sigClusterDepth; record = stats; title = "Cluster Depth"; );
66 |
67 |
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/src/AmacadWeightCluster.cc:
--------------------------------------------------------------------------------
1 | //
2 | // This program is free software: you can redistribute it and/or modify
3 | // it under the terms of the GNU Lesser General Public License as published by
4 | // the Free Software Foundation, either version 3 of the License, or
5 | // (at your option) any later version.
6 | //
7 | // This program is distributed in the hope that it will be useful,
8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | // GNU Lesser General Public License for more details.
11 | //
12 | // You should have received a copy of the GNU Lesser General Public License
13 | // along with this program. If not, see http://www.gnu.org/licenses/.
14 | //
15 |
16 | #include "BaseNetwLayer.h"
17 |
18 | #include
19 |
20 | #include "NetwControlInfo.h"
21 | #include "BaseMacLayer.h"
22 | #include "AddressingInterface.h"
23 | #include "SimpleAddress.h"
24 | #include "FindModule.h"
25 | #include "MdmacControlMessage_m.h"
26 | #include "ArpInterface.h"
27 | #include "NetwToMacControlInfo.h"
28 | #include "BaseMobility.h"
29 | #include "BaseConnectionManager.h"
30 | #include "ChannelAccess.h"
31 |
32 |
33 | #include "TraCIScenarioManager.h"
34 | #include "TraCIMobility.h"
35 |
36 | #include "AmacadWeightCluster.h"
37 |
38 |
39 | Define_Module(AmacadWeightCluster);
40 |
41 |
42 |
43 | /** @brief Initialization of the module and some variables*/
44 | void AmacadWeightCluster::initialize( int stage ) {
45 |
46 | MdmacNetworkLayer::initialize( stage );
47 | mIncludeDestination = true;
48 | if ( stage == 1 ) {
49 |
50 | mWeights[0] = par("distanceWeight").doubleValue();
51 | mWeights[1] = par("speedWeight").doubleValue();
52 | mWeights[2] = par("destinationWeight").doubleValue();
53 |
54 | // Load this car's destination list.
55 | GetDestinationList();
56 |
57 | // Schedule the change in destination.
58 | mChangeDestinationMessage = new cMessage( "changeDestination" );
59 | scheduleAt( simTime() + mDestinationSet[0].mTime, mChangeDestinationMessage );
60 |
61 | // Set up the first destination.
62 | mCurrentDestination = mDestinationSet[0].mDestination;
63 |
64 | // Clear the current destination in anticipation of the next one.
65 | mDestinationSet.erase( mDestinationSet.begin() );
66 |
67 | }
68 |
69 | }
70 |
71 |
72 |
73 | /** @brief Handle self messages */
74 | void AmacadWeightCluster::handleSelfMsg(cMessage* msg) {
75 |
76 | if ( mChangeDestinationMessage == msg ) {
77 |
78 | // We have to change the destination of our vehicle.
79 | if ( mDestinationSet.empty() )
80 | return;
81 |
82 | // Trigger the change in destination.
83 | scheduleAt( simTime() + mDestinationSet[0].mTime, mChangeDestinationMessage );
84 |
85 | // Set up the first destination.
86 | mCurrentDestination = mDestinationSet[0].mDestination;
87 |
88 | // Clear the current destination in anticipation of the next one.
89 | mDestinationSet.erase( mDestinationSet.begin() );
90 |
91 | return;
92 |
93 | } else {
94 |
95 | MdmacNetworkLayer::handleSelfMsg(msg);
96 |
97 | }
98 |
99 | }
100 |
101 |
102 | /** @brief Cleanup*/
103 | void AmacadWeightCluster::finish() {
104 |
105 | if ( mChangeDestinationMessage->isScheduled() )
106 | cancelEvent( mChangeDestinationMessage );
107 | delete mChangeDestinationMessage;
108 | MdmacNetworkLayer::finish();
109 |
110 | }
111 |
112 |
113 | /**
114 | * Get the destination from the destination file.
115 | */
116 | void AmacadWeightCluster::GetDestinationList() {
117 |
118 | mDestinationSet.clear();
119 |
120 | std::ifstream inputStream;
121 | inputStream.open( par("destinationFile").stringValue() );
122 | if ( inputStream.fail() )
123 | throw cRuntimeError( "Cannot load the destination file." );
124 |
125 |
126 | TraCIMobility *mob = dynamic_cast(mMobility);
127 | std::string carName, myName = mob->getExternalId();
128 | int count;
129 | DestinationEntry e;
130 | int entryCount;
131 | bool save;
132 |
133 | inputStream >> entryCount;
134 | for ( int i = 0; i < entryCount; i++ ) {
135 |
136 | inputStream >> carName >> count;
137 | save = ( carName == myName );
138 | for ( int j = 0; j < count; j++ ) {
139 |
140 | inputStream >> e.mTime >> e.mDestination.x >> e.mDestination.y;
141 | if ( save )
142 | mDestinationSet.push_back( e );
143 |
144 | }
145 |
146 | if ( save )
147 | break;
148 |
149 | }
150 |
151 | inputStream.close();
152 |
153 | }
154 |
155 |
156 |
157 | /** Add the destination data to a packet. */
158 | int AmacadWeightCluster::AddDestinationData( MdmacControlMessage *pkt ) {
159 |
160 | pkt->setXDestination( mCurrentDestination.x );
161 | pkt->setYDestination( mCurrentDestination.y );
162 | return 128;
163 |
164 | }
165 |
166 |
167 |
168 | /** Store the destination data from a packet. */
169 | void AmacadWeightCluster::StoreDestinationData( MdmacControlMessage *m ) {
170 |
171 | mNeighbours[m->getNodeId()].mDestination.x = m->getXDestination();
172 | mNeighbours[m->getNodeId()].mDestination.y = m->getYDestination();
173 |
174 | }
175 |
176 |
177 | /** @brief Compute the CH weight for this node. */
178 | double AmacadWeightCluster::calculateWeight() {
179 |
180 | if ( !mMobility || mNeighbours.size() == 0 )
181 | return -DBL_MAX;
182 |
183 | Coord p = mMobility->getCurrentPosition();
184 | Coord v = mMobility->getCurrentSpeed();
185 |
186 | double dL, dS, dD, ret = 0;
187 | for ( NeighbourIterator it = mNeighbours.begin(); it != mNeighbours.end(); it++ ) {
188 | dL = ( p - it->second.mPosition ).length();
189 | dS = ( v - it->second.mVelocity ).length();
190 | dD = ( mCurrentDestination - it->second.mDestination ).length();
191 | ret += dL * mWeights[0] + dS * mWeights[1] + dD * mWeights[2];
192 | }
193 |
194 | return -ret;
195 |
196 | }
197 |
--------------------------------------------------------------------------------
/src/AmacadWeightCluster.h:
--------------------------------------------------------------------------------
1 | //
2 | // This program is free software: you can redistribute it and/or modify
3 | // it under the terms of the GNU Lesser General Public License as published by
4 | // the Free Software Foundation, either version 3 of the License, or
5 | // (at your option) any later version.
6 | //
7 | // This program is distributed in the hope that it will be useful,
8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | // GNU Lesser General Public License for more details.
11 | //
12 | // You should have received a copy of the GNU Lesser General Public License
13 | // along with this program. If not, see http://www.gnu.org/licenses/.
14 | //
15 |
16 | #ifndef __CLUSTERLIB_AMACADWEIGHTCLUSTER_H_
17 | #define __CLUSTERLIB_AMACADWEIGHTCLUSTER_H_
18 |
19 | #include
20 |
21 | #include
22 | #include
23 |
24 | #include
25 | #include