Skip to content

Commit 2873032

Browse files
author
Aaron Roller
authored
Merge pull request #140 from AutoModality/AM-686/platform-req
feat: platform variant enforced for launch AM-686/platform-req
2 parents 8468d5c + c772819 commit 2873032

15 files changed

Lines changed: 480 additions & 3 deletions

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ if (CATKIN_ENABLE_TESTING)
224224
hz_config
225225
manual_to_disarming
226226
param
227+
platform_app_required_fail
228+
platform_app_required_pass
229+
platform_required_fail
230+
platform_required_pass
227231
primary
228232
ready_to_shutdown
229233
semi_auto_to_manual

include/am_super/super_node_mediator.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,23 @@ class SuperNodeMediator
4747
ros::Time last_contact; // last time a message was received from the node
4848
};
4949

50+
/**
51+
* Describes the platform configuration for the hardware running AMROS.
52+
* maker-model-app
53+
* Some variants are just the maker, some maker-model.
54+
* Sometimes a variant may provide just the app, indiciating the app could be flown on different platforms.
55+
*/
56+
struct PlatformVariant
57+
{
58+
/** the manufacture of the drone (DJI, ACSL)*/
59+
std::string maker;
60+
/** The product name of the drone specific to the maker (m210,m300,mini,pf2)*/
61+
std::string model;
62+
/** The application configuration for the mission (bridge, subt, etc). */
63+
std::string app;
64+
65+
};
66+
5067
struct Supervisor
5168
{
5269
/** map of all nodes in the system*/
@@ -288,6 +305,31 @@ class SuperNodeMediator
288305
*/
289306
bool forceTransition(const SuperState& to_state);
290307

308+
/**
309+
* Validates the actual platform matches the required.
310+
* Empty required platform will always return true.
311+
* App provided by itself will ensure the app is correct without concern for the maker/model.
312+
* dji_m300_bridge and acsl_pf2_bridge will both pass required app=bridge
313+
*
314+
* @returns true if the running platform has matching components for that required
315+
*/
316+
bool isCorrectPlatform(const PlatformVariant &required, const PlatformVariant &actual);
317+
318+
/** Given the string in the configurations, the variant given
319+
* is populated with the components parsed from the config
320+
* dji_m300 -> maker=dji,model=m300,app=""
321+
* dji_m300_bridge -> ...,app=bridge
322+
* */
323+
void platformConfigToVariant(const std::string config, PlatformVariant &variant);
324+
325+
/**
326+
* Converts the platform struct into a single string, separated by underscores
327+
* {maker}
328+
* {maker}_{model}
329+
* {maker}_{model}_{app}
330+
*/
331+
std::string platformVariantToConfig(const PlatformVariant &variant);
332+
291333
private:
292334
/** name of supervisor node */
293335
const std::string SUPER_NODE_NAME;

launch/am_super.launch

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<?xml version="1.0" ?>
22
<launch>
3+
<arg name="platform" value="$(eval optenv('AM_PLATFORM'))" />
34
<node pkg="am_super" type="am_super" name="am_super" output="screen">
4-
<rosparam command="load" file="$(find am_super)/launch/am_super.yaml"/>
5+
<rosparam command="load" file="$(find am_super)/launch/am_super.yaml" subst_value="true">
6+
<arg name="platform" value="$(arg platform)" />
7+
</rosparam>
58
</node>
69
</launch>

launch/am_super.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
platform:
3+
actual: $(arg platform)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <am_rostest_lib/am_rostest.h>
2+
3+
class PlatformAppRequiredFailTest : public RostestBase, am::AMLifeCycle
4+
{
5+
protected:
6+
7+
PlatformAppRequiredFailTest() : RostestBase() {
8+
}
9+
10+
};
11+
12+
TEST_F(PlatformAppRequiredFailTest, requiredPlatformInLaunchFile)
13+
{
14+
std::string missing = "missing";
15+
16+
std::string platform_required_param;
17+
ros::param::param<string>("/am_super/platform/required", platform_required_param, missing);
18+
ASSERT_EQ(platform_required_param,missing);
19+
20+
std::string platform_app_required_param;
21+
ros::param::param<string>("/am_super/platform/app/required", platform_app_required_param, missing);
22+
ASSERT_EQ(platform_app_required_param,"other");
23+
24+
std::string platform_actual_param;
25+
ros::param::param<string>("/am_super/platform/actual", platform_actual_param, missing);
26+
ASSERT_EQ(platform_actual_param,"maker_model_test");
27+
waitUntil(LifeCycleState::CONFIGURING,"LL88");
28+
waitUntil(LifeCycleState::FINALIZED,"88LL");
29+
waitUntilMissionState(brain_box_msgs::VxState::SHUTDOWN,"L8L8");
30+
}
31+
32+
int main(int argc, char** argv)
33+
{
34+
::testing::InitGoogleTest(&argc, argv);
35+
ros::init(argc, argv, ros::this_node::getName());
36+
37+
return RUN_ALL_TESTS();
38+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<launch>
2+
<!-- include test file and pass in this test node name -->
3+
<include file="$(find am_super)/rostest/am_super_rostest.test">
4+
<arg name="test_name" value="platform_app_required_fail"/>
5+
</include>
6+
<!-- only the app matters, the maker/model does not -->
7+
<rosparam param="/am_super/platform/app/required">other</rosparam>
8+
<rosparam param="/am_super/platform/actual">maker_model_test</rosparam>
9+
</launch>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <am_rostest_lib/am_rostest.h>
2+
3+
class PlatformAppRequiredPassTest : public RostestBase, am::AMLifeCycle
4+
{
5+
protected:
6+
7+
PlatformAppRequiredPassTest() : RostestBase() {
8+
}
9+
10+
};
11+
12+
TEST_F(PlatformAppRequiredPassTest, requiredPlatformInLaunchFile)
13+
{
14+
std::string missing = "missing";
15+
16+
std::string platform_required_param;
17+
ros::param::param<string>("/am_super/platform/required", platform_required_param, missing);
18+
ASSERT_EQ(platform_required_param,missing);
19+
20+
std::string platform_app_required_param;
21+
ros::param::param<string>("/am_super/platform/app/required", platform_app_required_param, missing);
22+
ASSERT_EQ(platform_app_required_param,"test");
23+
24+
std::string platform_actual_param;
25+
ros::param::param<string>("/am_super/platform/actual", platform_actual_param, missing);
26+
ASSERT_EQ(platform_actual_param,"maker_model_test");
27+
waitUntil(LifeCycleState::CONFIGURING,"XXSS");
28+
waitUntil(LifeCycleState::INACTIVE,"SSXX");
29+
waitUntilMissionState(brain_box_msgs::VxState::READY,"XSXS");
30+
}
31+
32+
int main(int argc, char** argv)
33+
{
34+
::testing::InitGoogleTest(&argc, argv);
35+
ros::init(argc, argv, ros::this_node::getName());
36+
37+
return RUN_ALL_TESTS();
38+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<launch>
2+
<!-- include test file and pass in this test node name -->
3+
<include file="$(find am_super)/rostest/am_super_rostest.test">
4+
<arg name="test_name" value="platform_app_required_pass"/>
5+
</include>
6+
<!-- only the app matters, the maker/model does not -->
7+
<rosparam param="/am_super/platform/app/required">test</rosparam>
8+
<rosparam param="/am_super/platform/actual">maker_model_test</rosparam>
9+
</launch>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <am_rostest_lib/am_rostest.h>
2+
3+
class PlatformRequiredFailTest : public RostestBase, am::AMLifeCycle
4+
{
5+
protected:
6+
7+
PlatformRequiredFailTest() : RostestBase() {
8+
}
9+
10+
};
11+
12+
TEST_F(PlatformRequiredFailTest, requiredPlatformDifferentThanActual)
13+
{
14+
std::string platform_required_param;
15+
ros::param::param<string>("/am_super/platform/required", platform_required_param, "missing");
16+
ASSERT_EQ(platform_required_param,"test");
17+
18+
std::string platform_actual_param;
19+
ros::param::param<string>("/am_super/platform/actual", platform_actual_param, "missing");
20+
ASSERT_EQ(platform_actual_param,"not_test");
21+
22+
waitUntil(LifeCycleState::CONFIGURING,"UIYT");
23+
waitUntil(LifeCycleState::FINALIZED,"23SS");
24+
waitUntilMissionState(brain_box_msgs::VxState::SHUTDOWN,"HYUJ");
25+
}
26+
27+
int main(int argc, char** argv)
28+
{
29+
::testing::InitGoogleTest(&argc, argv);
30+
ros::init(argc, argv, ros::this_node::getName());
31+
32+
return RUN_ALL_TESTS();
33+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<launch>
2+
<!-- include test file and pass in this test node name -->
3+
<include file="$(find am_super)/rostest/am_super_rostest.test">
4+
<arg name="test_name" value="platform_required_fail"/>
5+
</include>
6+
<rosparam param="/am_super/platform/required">test</rosparam>
7+
<rosparam param="/am_super/platform/actual">not_test</rosparam>
8+
</launch>

0 commit comments

Comments
 (0)