Skip to content

Latest commit

 

History

History
151 lines (110 loc) · 5.24 KB

README.md

File metadata and controls

151 lines (110 loc) · 5.24 KB

RSIA: Sample System

Sample System Architecture

Sample System Dependency Graph

Figure above shows a system dependency graph for a sample system to demonstrate the working of RSIA.

Note there are no colored edges as this graph is directly exported from a ROS utility rqt_graph which visualizes system state at runtime.

Now, let's look at system dependency graph as generated by the RSIA.

System Dependency Graph RSIA

Before going forward and looking at the impact analysis results, let's look at how to generate system dependency graph with rsia.

RSIA: Execution example

DA phase

ROS requirement: The workspace should be sourced. To source the sample workspace. Follow these steps:

  • Initiate workspace.
cd <rsia_repo>/examples/sample_ros_workspace/src
catkin_init_workspace
  • Compile workspace (Note: Here, we don't follow ROS's command catkin_make but instead use these commands which catkin performs in the background with some changed parameters to enable DA)
cd <rsia_repo>/examples/sample_ros_workspace
mkdir build
cd build
cmake ../src -DCMAKE_INSTALL_PREFIX=../install -DCATKIN_DEVEL_PREFIX=../devel -DCMAKE_CXX_COMPILER=$llvm_base_dir/build_llvm/libexec/c++-analyzer 
make
  • Source workspace
source <rsia_repo>/examples/sample_ros_workspace/devel/setup.bash

For IA to generate of system dependency graph, first we need to generate component level dump for each component in the system. This is done through running DA on each component.

We will show an example of DA on sensor node in sample_system and rest are similar:

  • Run DA_first_pass as:
cd <rsia_repo>/examples/sample_ros_workspace/build
$llvm_base_dir/build_llvm/bin/scan-build --use-analyzer=$llvm_base_dir/build_llvm/bin/clang -enable-checker debug.DumpRosPatterns make sensor_node --always-make

This will generate several log files within build/<packageName> folder.

  • Run DA_second_pass as:
cd <rsia_repo>/examples/sample_ros_workspace/build/sensor
DA_second_pass defaults

This will generate the following file:

- type: ROSNode
  name: Node
  label: /sensor
  color: none
  
- type: ROSTopic
  name: sensor
  label: /sensor
  color: none
  
- type: ROSEdge
  source: Node
  destination: sensor
  color: green
  label: none

Currently, developer manually changed the node name. Replace node name with the appropriate node name.

Repeat this process for other components. Namely:

  • arm_planner
  • arm_controller
  • base_planner
  • base_controller

We have also included already generated files for all these components under the folder IA_files.

IA phase

We will show the example for already added component dump example files in IA_files folder. You can follow the example with your generated component files.

First, we need to generate a launch file. Please generate one as specified here or use this one. Similarly, generate other input files (AffComp.txt FileList.txt StopColors.txt).

Once all the input files are generated, we can run IA phase as:

./GraphTraversal launch_ia.yaml

To just generate system dependency graph: Make StopColors.txt and AffComp.txt empty and run IA_tool again.

Output: System Dependency Graph RSIA

To Simulate:

  1. Traditional IA: Make StopColors.txt empty and put the changed component in AffComp.txt and run IA_tool.

Output: AffComp: sensor Impact Graph Traditional IA

  1. RSIA: Put green in StopColors.txt and put the changed component in AffComp.txt and run IA_tool. Note: green because we have modelled Independent edges as green, so the color choice is bound to our implementation.

Output: StopColor: green and AffComp: sensor Impact Graph RSIA

We can see that base_controller is not affected anymore because of an independent edge from base_planner component (ellipse) to base_planner topic (rectangle). This shows how RSIA can utilize rate information to reduce impact sets.

The reason why that link is Independent can be understood by looking at the source code of base_planner:

ros::Publisher base_planner_pub;
ros::Subscriber base_planner_sub;

void callback_subscriber(const std_msgs::Bool::ConstPtr& msg)
{
	//some processing
}

void callback_timer(const ros::TimerEvent&)
{
	std_msgs::Bool msg;
	//some processing
	base_planner_pub.publish(msg); 
}

int main(int argc, char **argv)
{
	ros::init(argc, argv, "base_controller");
	ros::NodeHandle n;
	
	base_planner_pub = n.advertise<std_msgs::Bool>("/base_planner",1000);
	base_planner_sub = n.subscribe("/sensor", 1000, callback_subscriber);

	//ros timer will ensure timly execution of the function callback_timer
	ros::Timer timer1 = n.createTimer(ros::Duration(0.1), callback_timer);

	//to wait for incoming messages and call the callback function as messages arrive.
	ros::spin();

	return 0;
}

Here, callback_timer is executed at a fixed rate by ros::Timer and since the component publishes through that callback, it is ensured that the message publishing rate is fixed of the incoming rate.