Skip to content

Commit

Permalink
[WIP] Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
ipa-nhg committed Feb 26, 2024
1 parent 88e566b commit 71d3f82
Show file tree
Hide file tree
Showing 21 changed files with 353 additions and 144 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 2 additions & 3 deletions haros_runner.sh → docker/haros_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,9 @@ then
then
if [ "${2}" = "--all" ]
then
python3 /call_generator.py
python3 /ros_model_extractor.py --clang-version $clang_version --package "$1" --"${3}" --model-path "${4}" --ws "${5}" --path-to-src "$path_to_src_code" --repo $model_repo -a >> ${4}/extractor.log
python3 /ros_code_analysis/ros_model_extractor.py --clang-version $clang_version --package "$1" --"${3}" --model-path "${4}" --ws "${5}" --path-to-src "$path_to_src_code" --repo $model_repo -a >> ${4}/extractor.log
else
python3 /ros_model_extractor.py --clang-version $clang_version --package "$1" --name "$2" --"${3}" --model-path "${4}" --ws "${5}" --path-to-src "$path_to_src_code" --repo $model_repo>> ${4}/extractor.log
python3 /ros_code_analysis/ros_model_extractor.py --clang-version $clang_version --package "$1" --name "$2" --"${3}" --model-path "${4}" --ws "${5}" --path-to-src "$path_to_src_code" --repo $model_repo>> ${4}/extractor.log
fi
else
echo "Python version not supported"
Expand Down
14 changes: 6 additions & 8 deletions humble/Dockerfile → docker/humble/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ RUN echo "extractor ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/extra
USER extractor
RUN mkdir -p /home/extractor/ws/src
#RUN git clone https://github.com/ipa320/ros2model.git /home/extractor/ws/src/ros2model
RUN echo "test"
RUN git clone https://github.com/ipa-nhg/ros2model.git -b PythonInstallTemplatesFolder /home/extractor/ws/src/ros2model

RUN mkdir -p /home/extractor/results
Expand All @@ -58,7 +57,7 @@ RUN if [ $enable_ssh ] ; then mkdir -p /home/extractor/.ssh/ && \
touch /home/extractor/.ssh/config && \
chmod 600 /home/extractor/.ssh/config ; fi

COPY --chown=extractor:root ssh_config/ /keys/
COPY --chown=extractor:root docker/ssh_config/ /keys/
RUN if [ $enable_ssh ] ; then cat /keys/ssh_key.pub >> /home/extractor/.ssh/authorized_keys ; fi
RUN if [ $enable_ssh ] ; then cat /keys/config >> /home/extractor/.ssh/config ; fi
####
Expand All @@ -75,13 +74,12 @@ ENV PYTHON_VERSION 3
RUN echo 'source /home/extractor/ws/install/setup.bash' >> /home/extractor/.bashrc

RUN echo "test"
COPY ${path_to_scripts}messages_generator_runner.sh /
COPY ${path_to_scripts}generate_messages_model_helper.sh /
COPY ${path_to_scripts}haros_runner.sh /
COPY ${path_to_scripts}ros_model_extractor.py /
COPY ${path_to_scripts}call_generator.py /
#COPY ${path_to_scripts}messages_generator_runner.sh /
#COPY ${path_to_scripts}generate_messages_model_helper.sh /
COPY docker/haros_runner.sh /
COPY ros_code_analysis /

COPY ${path_to_scripts}test.sh /
COPY helper_scripts/test.sh /

EXPOSE 4005
#CMD sudo chown -R extractor:extractor /home/extractor/results
File renamed without changes.
File renamed without changes.
File renamed without changes.
16 changes: 9 additions & 7 deletions noetic/Dockerfile → docker/noetic/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ ENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:/usr/lib/llvm-10/lib
RUN pip3 install --upgrade pip
RUN pip3 install -Iv clang==10.0.1
RUN pip3 install -e git+https://github.com/timtadh/pyflwor.git#egg=pyflwor
RUN pip3 install -e git+https://github.com/ipa320/ros_model_parser.git#egg=ros_model_parser
#RUN pip3 install -e git+https://github.com/ipa320/ros_model_parser.git#egg=ros_model_parser
RUN pip3 install -e git+https://github.com/git-afsantos/bonsai#egg=bonsai-code
RUN pip3 install -e git+https://github.com/ipa-nhg/haros@FixPythonExtractTopic#egg=haros
# RUN pip3 install -e git+https://github.com/git-afsantos/haros#egg=haros
RUN pip3 install -e git+https://github.com/ipa320/ros2model.git#egg=ros2model

RUN apt-get update && apt-get install -y ros-noetic-desktop && apt upgrade -y

Expand All @@ -56,7 +57,7 @@ RUN if [ $enable_ssh ] ; then mkdir -p /home/extractor/.ssh/ && \
touch /home/extractor/.ssh/config && \
chmod 600 /home/extractor/.ssh/config ; fi

COPY --chown=extractor:root ssh_config/ /keys/
COPY --chown=extractor:root docker/ssh_config/ /keys/
RUN if [ $enable_ssh ] ; then cat /keys/ssh_key.pub >> /home/extractor/.ssh/authorized_keys ; fi
RUN if [ $enable_ssh ] ; then cat /keys/config >> /home/extractor/.ssh/config ; fi
####
Expand All @@ -75,11 +76,12 @@ RUN source /opt/ros/$ROS_DISTRO/setup.bash;\
ENV PYTHON_VERSION 3
RUN echo 'source /home/extractor/ws/devel/setup.bash' >> /home/extractor/.bashrc

COPY ${path_to_scripts}messages_generator_runner.sh /
COPY ${path_to_scripts}generate_messages_model_helper.sh /
COPY ${path_to_scripts}haros_runner.sh /
COPY ${path_to_scripts}ros_model_extractor.py /
COPY ${path_to_scripts}test.sh /
#COPY ${path_to_scripts}messages_generator_runner.sh /
#COPY ${path_to_scripts}generate_messages_model_helper.sh /
COPY docker/haros_runner.sh /
COPY ros_code_analysis /

COPY helper_scripts/test.sh /

EXPOSE 4004
#CMD sudo chown -R extractor:extractor /home/extractor/results
File renamed without changes.
File renamed without changes.
44 changes: 0 additions & 44 deletions haros_runner.py

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
Empty file.
140 changes: 140 additions & 0 deletions ros_code_analysis/ros_code_analysis/ros1_cpp_extractor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#!/usr/bin/env python
#
# Copyright 2024 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
#
# Nadia Hammoudeh Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from bonsai.analysis import CodeQuery, resolve_expression
from ros_common_extractor import RosCommonExtractor
import ros2model.core.metamodels.metamodel_ros as RosModelMetamodel

class Ros1CppExtractor():
def extract_primitives(node, parser, analysis):
gs = parser.global_scope
node.source_tree = parser.global_scope
publishers=[]
subscribers=[]
serviceservers=[]
serviceclients=[]
actionservers=[]
actionclients=[]
parameters=[]
for call in (CodeQuery(gs).all_calls.get()):
for call in (CodeQuery(gs).all_calls.where_name("SimpleActionServer").get()):
if len(call.arguments) > 0:
name = analysis._extract_action(call)
action_type = analysis._extract_action_type(call).split("_<",1)[0]
if name!="?" or act_type!="?":
acs = RosModelMetamodel.ActionServer(name=name,type=act_type.replace(".action",""))
actionservers.append(acs)
for call in (CodeQuery(gs).all_calls.where_name("SimpleActionClient").get()):
if len(call.arguments) > 0:
name = analysis._extract_action(call)
action_type = analysis._extract_action_type(call).split("_<",1)[0]
if name!="?" or act_type!="?":
ac = RosModelMetamodel.ActionServer(name=name,type=act_type.replace(".action",""))
actionclients.append(ac)
for call in (CodeQuery(gs).all_calls.where_name("advertise").where_result("ros::Publisher").get()):
if len(call.arguments) > 1:
name = analysis._extract_topic(call, topic_pos=0)
msg_type = analysis._extract_message_type(call)
queue_size = analysis._extract_queue_size(call, queue_pos=1)
if name!="?" or msg_type!="?":
pub = RosModelMetamodel.Publisher(name=name,type=msg_type.replace(".msg",""))
publishers.append(pub)
for call in (CodeQuery(gs).all_calls.where_name("subscribe").where_result("ros::Subscriber").get()):
if len(call.arguments) > 1:
name = analysis._extract_topic(call, topic_pos=0)
msg_type = analysis._extract_message_type(call)
queue_size = analysis._extract_queue_size(call, queue_pos=1)
if name!="?" or msg_type!="?":
sub = RosModelMetamodel.Subscriber(name=name,type=msg_type.replace(".msg",""))
subscribers.append(sub)
for call in (CodeQuery(gs).all_calls.where_name("advertiseService").where_result("ros::ServiceServer").get()):
if len(call.arguments) > 1:
name = analysis._extract_topic(call)
srv_type = analysis._extract_message_type(call)
if name!="?" or srv_type!="?":
ss = RosModelMetamodel.ServiceServer(name=name,type=srv_type.replace(".srv","").replace("Request",""))
serviceservers.append(ss)
for call in (CodeQuery(gs).all_calls.where_name("serviceClient").where_result("ros::ServiceClient").get()):
if len(call.arguments) > 1:
name = analysis._extract_topic(call)
srv_type = analysis._extract_message_type(call)
if name!="?" or srv_type!="?":
sc = RosModelMetamodel.ServiceClient(name=name,type=srv_type.replace(".srv","").replace("Response",""))
serviceclients.append(sc)

#PARAMETERS nhg:this needs review
nh_prefix = "c:@N@ros@S@NodeHandle@"
gets = ("getParam", "getParamCached", "param")
reads = gets + ("hasParam", "searchParam")
sets = ("setParam",)
writes = sets + ("deleteParam",)
for call in CodeQuery(gs).all_calls.where_name(reads).get():
if (call.full_name.startswith("ros::NodeHandle") or (isinstance(call.reference, str) and call.reference.startswith(nh_prefix))):
param_type = default_value = None
param_name = analysis._extract_topic(call)
if call.name in gets:
param_type = RosCommonExtractor.transform_type(analysis._extract_param_type(call.arguments[1]))
if call.name == "param":
if len(call.arguments) > 2:
default_value = analysis._extract_param_value( call, arg_pos=2)
elif len(call.arguments) == 2:
default_value = analysis._extract_param_value( call, arg_pos=1)
if not ((default_value is None or default_value == "") and param_type is None):
param = RosModelMetamodel.Parameter(name=param_name,type=param_type,value=default_value)
parameters.append(param)

for call in CodeQuery(gs).all_calls.where_name(writes).get():
if (call.full_name.startswith("ros::NodeHandle") or (isinstance(call.reference, str) and call.reference.startswith(nh_prefix))):
param_type = value = None
param_name = analysis._extract_topic(call)
if len(call.arguments) >= 2 and call.name in sets:
param_type = RosCommonExtractor.transform_type(analysis._extract_param_type(call.arguments[1]))
value = analysis._extract_param_value(call, arg_pos=1)
if not ((default_value is None or default_value == "") and param_type is None):
param = RosModelMetamodel.Parameter(name=param_name,type=param_type,value=default_value)
parameters.append(param)
ros_prefix = "c:@N@ros@N@param@"
gets = ("get", "getCached", "param")
reads = gets + ("has",)
sets = ("set",)
writes = sets + ("del",)
for call in CodeQuery(gs).all_calls.where_name(reads).get():
if (call.full_name.startswith("ros::param") or (isinstance(call.reference, str) and call.reference.startswith(ros_prefix))):
param_type = default_value = None
param_name = analysis._extract_topic(call)
if call.name == "param":
if call.name in gets:
param_type = RosCommonExtractor.transform_type(analysis._extract_param_type(call.arguments[1]))
if len(call.arguments) > 2:
default_value = analysis._extract_param_value(call, arg_pos=2)
elif len(call.arguments) == 2:
default_value = analysis._extract_param_value(call, arg_pos=1)
if not ((default_value is None or default_value == "") and param_type is None):
param = RosModelMetamodel.Parameter(name=param_name,type=param_type,value=default_value)
parameters.append(param)
for call in CodeQuery(gs).all_calls.where_name(writes).get():
if (call.full_name.startswith("ros::param") or (isinstance(call.reference, str) and call.reference.startswith(ros_prefix))):
param_type = value = None
if len(call.arguments) >= 2 and call.name in sets:
param_type = RosCommonExtractor.transform_type(analysis._extract_param_type(call.arguments[1]))
value = analysis._extract_param_value(call, arg_pos=1)
param_name = analysis._extract_topic(call)
if not ((default_value is None or default_value == "") and param_type is None):
param = RosModelMetamodel.Parameter(name=param_name,type=param_type,value=default_value)
parameters.append(param)
return publishers, subscribers, serviceservers, serviceclients, actionservers, actionclients, parameters
94 changes: 94 additions & 0 deletions ros_code_analysis/ros_code_analysis/ros2_cpp_extractor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env python
#
# Copyright 2024 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
#
# Nadia Hammoudeh Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from bonsai.analysis import CodeQuery, resolve_expression
from ros_common_extractor import RosCommonExtractor
import ros2model.core.metamodels.metamodel_ros as RosModelMetamodel

class Ros2CppExtractor():
def extract_primitives(node, parser, analysis):
gs = parser.global_scope
node.source_tree = parser.global_scope
publishers=[]
subscribers=[]
serviceservers=[]
serviceclients=[]
actionservers=[]
actionclients=[]
parameters=[]
for call in (CodeQuery(gs).all_calls.get()):
if "Publisher" in str(call):
if len(call.arguments) > 1:
name = analysis._extract_topic(call, topic_pos=0)
msg_type = analysis._extract_message_type(call)
queue_size = analysis._extract_queue_size(call, queue_pos=1)
if name!="?" or msg_type!="?":
pub = RosModelMetamodel.Publisher(name=name,type=msg_type.replace(".msg",""))
publishers.append(pub)
if "Subscription" in str(call): # Subscription or Subscriber?
if len(call.arguments) > 1:
name = analysis._extract_topic(call, topic_pos=0)
msg_type = analysis._extract_message_type(call)
queue_size = analysis._extract_queue_size(call, queue_pos=1)
if name!="?" or msg_type!="?":
sub = RosModelMetamodel.Subscriber(name=name,type=msg_type.replace(".msg",""))
subscribers.append(sub)
if "Service" in str(call) and "::srv::" in str(call): #or?
if len(call.arguments) > 1:
name = analysis._extract_topic(call, topic_pos=0)
srv_type = analysis._extract_message_type(call)
queue_size = analysis._extract_queue_size(call, queue_pos=1)
if name!="?" or srv_type!="?":
ss = RosModelMetamodel.ServiceServer(name=name,type=srv_type.replace(".srv",""))
serviceservers.append(ss)
if "Client" in str(call) and "::srv::" in str(call):
if len(call.arguments) > 1:
name = analysis._extract_topic(call, topic_pos=0)
srv_type = analysis._extract_message_type(call)
queue_size = analysis._extract_queue_size(call, queue_pos=1)
if name!="?" or srv_type!="?":
sc = RosModelMetamodel.ServiceClient(name=name,type=srv_type.replace(".srv",""))
serviceclients.append(sc)
if "Server" in str(call) and "::action::" in str(call):
if len(call.arguments) > 1:
name = analysis._extract_topic(call, topic_pos=0)
act_type = analysis._extract_message_type(call)
queue_size = analysis._extract_queue_size(call, queue_pos=1)
if name!="?" or act_type!="?":
acs = RosModelMetamodel.ActionServer(name=name,type=act_type.replace(".action",""))
actionservers.append(acs)
if "Client" in str(call) and "::action::" in str(call):
if len(call.arguments) > 1:
name = analysis._extract_topic(call, topic_pos=0)
act_type = analysis._extract_message_type(call)
queue_size = analysis._extract_queue_size(call, queue_pos=1)
if name!="?" or act_type!="?":
ac = RosModelMetamodel.ActionServer(name=name,type=act_type.replace(".action",""))
actionclients.append(ac)
if "declare_parameter" in str(call):
if len(call.arguments) > 1:
name = analysis._extract_topic(call, topic_pos=0)
default_value = resolve_expression(call.arguments[1])
param_type = RosCommonExtractor.transform_type(resolve_expression(call))
if not default_value:
param = RosModelMetamodel.Parameter(name=name,type=param_type)
else:
param = RosModelMetamodel.Parameter(name=name,type=param_type,value=str(default_value))
parameters.append(param)

return publishers, subscribers, serviceservers, serviceclients, actionservers, actionclients, parameters
Loading

0 comments on commit 71d3f82

Please sign in to comment.