From 21397905ac805ae52089a93e3969c9beb87d305f Mon Sep 17 00:00:00 2001 From: Chris Burbridge Date: Wed, 30 Sep 2015 17:01:43 +0100 Subject: [PATCH 1/8] Add TPCC QSR. --- qsr_lib/scripts/tpcc_test.py | 50 +++++++ qsr_lib/src/qsrlib_qsrs/__init__.py | 5 +- qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py | 83 ++++++++++++ .../qsrlib_qsrs/qsr_triadic_abstractclass.py | 124 ++++++++++++++++++ .../combinations_and_permutations.py | 6 + 5 files changed, 266 insertions(+), 2 deletions(-) create mode 100755 qsr_lib/scripts/tpcc_test.py create mode 100644 qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py create mode 100644 qsr_lib/src/qsrlib_qsrs/qsr_triadic_abstractclass.py diff --git a/qsr_lib/scripts/tpcc_test.py b/qsr_lib/scripts/tpcc_test.py new file mode 100755 index 0000000..536c641 --- /dev/null +++ b/qsr_lib/scripts/tpcc_test.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function, division +from qsrlib.qsrlib import QSRlib, QSRlib_Request_Message +from qsrlib_io.world_trace import Object_State, World_Trace +import argparse + +def pretty_print_world_qsr_trace(which_qsr, qsrlib_response_message): + print(which_qsr, "request was made at ", str(qsrlib_response_message.req_made_at) + + " and received at " + str(qsrlib_response_message.req_received_at) + + " and finished at " + str(qsrlib_response_message.req_finished_at)) + print("---") + print("Response is:") + for t in qsrlib_response_message.qsrs.get_sorted_timestamps(): + foo = str(t) + ": " + for k, v in zip(qsrlib_response_message.qsrs.trace[t].qsrs.keys(), + qsrlib_response_message.qsrs.trace[t].qsrs.values()): + foo += str(k) + ":" + str(v.qsr) + "; " + print(foo) + +if __name__ == "__main__": + # ************************************************************************************** + # create a QSRlib object if there isn't one already + qsrlib = QSRlib() + + # ************************************************************************************** + # parse command line arguments + which_qsr = "tpcc" + + # ************************************************************************************** + # make some input data + world = World_Trace() + + o1 = [Object_State(name="o1", timestamp=0, x=2., y=4., xsize=5., ysize=8.)] + o2 = [Object_State(name="o2", timestamp=0, x=6., y=5., xsize=5., ysize=8.)] + o3 = [Object_State(name="o3", timestamp=0, x=5., y=2., xsize=5.2, ysize=8.5)] + + world.add_object_state_series(o1) + world.add_object_state_series(o2) + world.add_object_state_series(o3) + + # ************************************************************************************** + # make a QSRlib request message + qsrlib_request_message = QSRlib_Request_Message(which_qsr=which_qsr, input_data=world) + # request your QSRs + qsrlib_response_message = qsrlib.request_qsrs(req_msg=qsrlib_request_message) + + # ************************************************************************************* + # print out your QSRs + pretty_print_world_qsr_trace(which_qsr, qsrlib_response_message) diff --git a/qsr_lib/src/qsrlib_qsrs/__init__.py b/qsr_lib/src/qsrlib_qsrs/__init__.py index 849497b..595f637 100644 --- a/qsr_lib/src/qsrlib_qsrs/__init__.py +++ b/qsr_lib/src/qsrlib_qsrs/__init__.py @@ -12,7 +12,7 @@ from qsr_moving_or_stationary import QSR_Moving_or_Stationary from qsr_new_mwe import QSR_MWE from qsr_ra import QSR_RA - +from qsr_tpcc import QSR_TPCC # register new qsrs by class name below qsrs_registry = (QSR_RCC2, QSR_RCC3_Rectangle_Bounding_Boxes_2D, @@ -27,4 +27,5 @@ QSR_Arg_Prob_Relations_Distance, QSR_Moving_or_Stationary, QSR_MWE, - QSR_RA) + QSR_RA, + QSR_TPCC) diff --git a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py new file mode 100644 index 0000000..3dbaa0d --- /dev/null +++ b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function, division +from qsrlib_qsrs.qsr_triadic_abstractclass import QSR_Triadic_1t_Abstractclass +import math + + +import sys +import math + +NUMBER_OF_PARTITIONS = 8 +PARTITION_SIZE = (2.0 * math.pi) / NUMBER_OF_PARTITIONS + +def relative_angle(a, b, c): + # compute relative angle (left/right/straight, front/back/straight) + angle_BA = math.atan2((b.y - a.y),(b.x - a.x)) + + if angle_BA < 0: + angle_BA += 2 * math.pi + + angle_CB = math.atan2((c.y - b.y), (c.x - b.x)) + if angle_CB < 0: + angle_CB += 2 * math.pi + + angle_rel = angle_CB - angle_BA + if angle_rel < 0: + angle_rel += 2 * math.pi + + return angle_rel + +def partition(angle): + return int(angle / PARTITION_SIZE) + +def partition_name(p): + if p == 0: + return 'bl' + elif p == 1: + return 'lb' + elif p == 2: + return 'lf' + elif p == 3: + return 'fl' + elif p == 4: + return 'fr' + elif p == 5: + return 'rf' + elif p == 6: + return 'rb' + else: # p ==7 + return 'br' + + +def calc_TPCC(origin, relatum, objct): + + base_distance = math.sqrt((origin.x-relatum.x)**2 + (origin.y-relatum.y)**2) + object_distance = math.sqrt((objct.x-relatum.x)**2 + (objct.y-relatum.y)**2) + if base_distance == object_distance: + return "sam" + + relation = "d" if object_distance > base_distance else "c" # is it far or close: first letter + + rela = relative_angle(origin, relatum, objct) + + part = partition(rela) #TODO: the "*s*" relations + relation+=partition_name(part) + + return relation + + +class QSR_TPCC(QSR_Triadic_1t_Abstractclass): + """ TPCC QSRs. + .. seealso:: For further details about TPCC, see http://www.sfbtr8.spatial-cognition.de/project/r3/QualitativeCalculi/TPCC/index.html. + """ + _unique_id = "tpcc" + _all_possible_relations = ("dlf,dfl,dsl,dbl,dlb,dsb,drb,dbr,dsr,dfr,drf,dsf," + "clf,cfl,csl,cbl,clb,csb,crb,cbr,csr,cfr,crf,csf,sam").split(",") + _dtype = "points" + + def __init__(self): + """Constructor.""" + super(QSR_TPCC, self).__init__() + + def _compute_qsr(self, origin, relatum, objct, qsr_params, **kwargs): + return calc_TPCC(origin, relatum, objct) diff --git a/qsr_lib/src/qsrlib_qsrs/qsr_triadic_abstractclass.py b/qsr_lib/src/qsrlib_qsrs/qsr_triadic_abstractclass.py new file mode 100644 index 0000000..433028e --- /dev/null +++ b/qsr_lib/src/qsrlib_qsrs/qsr_triadic_abstractclass.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function, division +from abc import ABCMeta, abstractmethod +from qsrlib_qsrs.qsr_abstractclass import QSR_Abstractclass +from qsrlib_utils.combinations_and_permutations import * +from qsrlib_io.world_qsr_trace import * + +class QSR_Triadic_Abstractclass(QSR_Abstractclass): + """Abstract class of triadic QSRs, i.e. QSRs that are computed over three objects.""" + + __metaclass__ = ABCMeta + + def __init__(self): + """Constructor.""" + super(QSR_Triadic_Abstractclass, self).__init__() + + def _init_qsrs_for_default(self, objects_names_of_world_state): + """Default list of entities for which QSRs are to be computed for. + + :param objects_names_of_world_state: Objects names at a world state. + :type objects_names_of_world_state: list of str + :return: The permutations, i.e. all possible pairs including mirrors, of the list of names passed in the + arguments. E.g. for `objects_names_of_world_state = ['a', 'b']` return `[('a', 'b'), ('b', 'a')]`. + :rtype: list of tuples of str + """ + return possible_triplets(objects_names_of_world_state) + + def _validate_qsrs_for(self, qsrs_for): + """Validate `qsrs_for` which must be a list of tuples of three objects names. + + :param qsrs_for: The original `qsrs_for` that needs validation. + :type qsrs_for: list + :return: List of string objects names to make QSRs, which might be the same as the argument `qsrs_for` or a + subset of it with elements that passed the validation test, i.e. the elements of the list must be tuples of + three strings. + :rtype: list + """ + return [p for p in qsrs_for if isinstance(p, (list, tuple)) and (len(p) == 3)] + + def _return_points(self, data1, data2, data3): + """Return the arguments as they are in their point form. + + :param data1: First object data. + :type data1: :class:`Object_State ` + :param data2: Second object data. + :type data2: :class:`Object_State ` + :param data3: Third object data. + :type data3: :class:`Object_State ` + :return: `data1`, `data2`, `data3` + :rtype: qsrlib_io.world_trace.Object_State, qsrlib_io.world_trace.Object_State + """ + return data1, data2, data3 + + def _return_bounding_boxes_2d(self, data1, data2, data3): + """Return the 2D bounding boxes of the arguments. + + :param data1: First object data. + :type data1: :class:`Object_State ` + :param data2: Second object data. + :type data2: :class:`Object_State ` + :param data3: Third object data. + :type data3: :class:`Object_State ` + :return: `bbox1`, `bbox2`, `bbox3` + :rtype: list of floats, list of floats + """ + return data1.return_bounding_box_2d(), data2.return_bounding_box_2d(), data3.return_bounding_box_2d() + + +class QSR_Triadic_1t_Abstractclass(QSR_Triadic_Abstractclass): + """Special case abstract class of triadic QSRs. Works with triadic QSRs that require data over one timestamp.""" + + __metaclass__ = ABCMeta + + def __init__(self): + """Constructor.""" + super(QSR_Triadic_1t_Abstractclass, self).__init__() + + @abstractmethod + def _compute_qsr(self, data1, data2, data3, qsr_params, **kwargs): + """Compute QSR value. + + :param data1: First object data. + :type data1: :class:`Object_State ` + :param data2: Second object data. + :type data2: :class:`Object_State ` + :param data3: Third object data. + :type data3: :class:`Object_State ` + :param qsr_params: QSR specific parameters passed in `dynamic_args`. + :type qsr_params: dict + :param kwargs: kwargs arguments. + :return: Computed QSR value. + :rtype: str + """ + return + + def make_world_qsr_trace(self, world_trace, timestamps, qsr_params, req_params, **kwargs): + """Compute the world QSR trace from the arguments. + + :param world_trace: Input data. + :type world_trace: :class:`World_Trace ` + :param timestamps: List of sorted timestamps of `world_trace`. + :type timestamps: list + :param qsr_params: QSR specific parameters passed in `dynamic_args`. + :type qsr_params: dict + :param req_params: Request parameters. + :type req_params: dict + :param kwargs: kwargs arguments. + :return: Computed world QSR trace. + :rtype: :class:`World_QSR_Trace ` + """ + ret = World_QSR_Trace(qsr_type=self._unique_id) + for t in timestamps: + world_state = world_trace.trace[t] + qsrs_for = self._process_qsrs_for(world_state.objects.keys(), req_params["dynamic_args"]) + for p in qsrs_for: + between = ",".join(p) + try: + data1, data2, data3 = self._dtype_map[self._dtype](world_state.objects[p[0]], world_state.objects[p[1]], world_state.objects[p[2]]) + except KeyError: + raise KeyError("%s is not a valid value, should be one of %s" % (self._dtype, self._dtype_map.keys())) + ret.add_qsr(QSR(timestamp=t, between=between, + qsr=self._format_qsr(self._compute_qsr(data1, data2, data3, qsr_params, **kwargs))), + t) + return ret diff --git a/qsr_lib/src/qsrlib_utils/combinations_and_permutations.py b/qsr_lib/src/qsrlib_utils/combinations_and_permutations.py index 4291254..b3593e4 100644 --- a/qsr_lib/src/qsrlib_utils/combinations_and_permutations.py +++ b/qsr_lib/src/qsrlib_utils/combinations_and_permutations.py @@ -39,3 +39,9 @@ def possible_pairs_between_two_lists(s1, s2, mirrors=True): """ s1, s2 = set(s1), set(s2) return list(itertools.product(s1, s2)) + list(itertools.product(s2, s1)) if mirrors else list(itertools.product(s1, s2)) + +def possible_triplets(s, mirrors=True): + """ + Return the possible triplets from the list s. + """ + return list(itertools.permutations(set(s), 3)) if mirrors else list(itertools.combinations(set(s), 3)) From 7dee151ebd3047d47d99666f44dc02081adb847e Mon Sep 17 00:00:00 2001 From: Chris Burbridge Date: Thu, 1 Oct 2015 10:55:52 +0100 Subject: [PATCH 2/8] Put tpcc_test back into mwe.py. --- qsr_lib/scripts/mwe.py | 23 ++++++++++++----- qsr_lib/scripts/tpcc_test.py | 50 ------------------------------------ 2 files changed, 17 insertions(+), 56 deletions(-) delete mode 100755 qsr_lib/scripts/tpcc_test.py diff --git a/qsr_lib/scripts/mwe.py b/qsr_lib/scripts/mwe.py index 95dbb46..49b5ee8 100755 --- a/qsr_lib/scripts/mwe.py +++ b/qsr_lib/scripts/mwe.py @@ -37,13 +37,24 @@ def pretty_print_world_qsr_trace(which_qsr, qsrlib_response_message): # **************************************************************************************************** # make some input data world = World_Trace() - o1 = [Object_State(name="o1", timestamp=0, x=1., y=1., xsize=5., ysize=8.), - Object_State(name="o1", timestamp=1, x=1., y=2., xsize=5., ysize=8.)] + if which_qsr == "tpcc": + # Then we need three objects to do a test... + # Don't bother with more than one timestamp. + o1 = [Object_State(name="o1", timestamp=0, x=2., y=4., xsize=5., ysize=8.)] + o2 = [Object_State(name="o2", timestamp=0, x=6., y=5., xsize=5., ysize=8.)] + o3 = [Object_State(name="o3", timestamp=0, x=5., y=2., xsize=5.2, ysize=8.5)] - o2 = [Object_State(name="o2", timestamp=0, x=11., y=1., xsize=5., ysize=8.), - Object_State(name="o2", timestamp=1, x=1., y=2., xsize=5., ysize=8.)] - world.add_object_state_series(o1) - world.add_object_state_series(o2) + world.add_object_state_series(o1) + world.add_object_state_series(o2) + world.add_object_state_series(o3) + else: + o1 = [Object_State(name="o1", timestamp=0, x=1., y=1., xsize=5., ysize=8.), + Object_State(name="o1", timestamp=1, x=1., y=2., xsize=5., ysize=8.)] + + o2 = [Object_State(name="o2", timestamp=0, x=11., y=1., xsize=5., ysize=8.), + Object_State(name="o2", timestamp=1, x=1., y=2., xsize=5., ysize=8.)] + world.add_object_state_series(o1) + world.add_object_state_series(o2) # **************************************************************************************************** # make a QSRlib request message diff --git a/qsr_lib/scripts/tpcc_test.py b/qsr_lib/scripts/tpcc_test.py deleted file mode 100755 index 536c641..0000000 --- a/qsr_lib/scripts/tpcc_test.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -from __future__ import print_function, division -from qsrlib.qsrlib import QSRlib, QSRlib_Request_Message -from qsrlib_io.world_trace import Object_State, World_Trace -import argparse - -def pretty_print_world_qsr_trace(which_qsr, qsrlib_response_message): - print(which_qsr, "request was made at ", str(qsrlib_response_message.req_made_at) - + " and received at " + str(qsrlib_response_message.req_received_at) - + " and finished at " + str(qsrlib_response_message.req_finished_at)) - print("---") - print("Response is:") - for t in qsrlib_response_message.qsrs.get_sorted_timestamps(): - foo = str(t) + ": " - for k, v in zip(qsrlib_response_message.qsrs.trace[t].qsrs.keys(), - qsrlib_response_message.qsrs.trace[t].qsrs.values()): - foo += str(k) + ":" + str(v.qsr) + "; " - print(foo) - -if __name__ == "__main__": - # ************************************************************************************** - # create a QSRlib object if there isn't one already - qsrlib = QSRlib() - - # ************************************************************************************** - # parse command line arguments - which_qsr = "tpcc" - - # ************************************************************************************** - # make some input data - world = World_Trace() - - o1 = [Object_State(name="o1", timestamp=0, x=2., y=4., xsize=5., ysize=8.)] - o2 = [Object_State(name="o2", timestamp=0, x=6., y=5., xsize=5., ysize=8.)] - o3 = [Object_State(name="o3", timestamp=0, x=5., y=2., xsize=5.2, ysize=8.5)] - - world.add_object_state_series(o1) - world.add_object_state_series(o2) - world.add_object_state_series(o3) - - # ************************************************************************************** - # make a QSRlib request message - qsrlib_request_message = QSRlib_Request_Message(which_qsr=which_qsr, input_data=world) - # request your QSRs - qsrlib_response_message = qsrlib.request_qsrs(req_msg=qsrlib_request_message) - - # ************************************************************************************* - # print out your QSRs - pretty_print_world_qsr_trace(which_qsr, qsrlib_response_message) From 1172b2e54dfdf2f59acc079a5ff2dda84c9b12b9 Mon Sep 17 00:00:00 2001 From: Chris Burbridge Date: Thu, 1 Oct 2015 10:59:48 +0100 Subject: [PATCH 3/8] Use tuple of types instead of list. --- qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py index 3dbaa0d..6fc5e4a 100644 --- a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py +++ b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py @@ -71,8 +71,10 @@ class QSR_TPCC(QSR_Triadic_1t_Abstractclass): .. seealso:: For further details about TPCC, see http://www.sfbtr8.spatial-cognition.de/project/r3/QualitativeCalculi/TPCC/index.html. """ _unique_id = "tpcc" - _all_possible_relations = ("dlf,dfl,dsl,dbl,dlb,dsb,drb,dbr,dsr,dfr,drf,dsf," - "clf,cfl,csl,cbl,clb,csb,crb,cbr,csr,cfr,crf,csf,sam").split(",") + _all_possible_relations = ('dlf', 'dfl', 'dsl', 'dbl', 'dlb', 'dsb', 'drb', 'dbr', + 'dsr', 'dfr', 'drf', 'dsf', 'clf', 'cfl', 'csl', 'cbl', + 'clb', 'csb', 'crb', 'cbr', 'csr', 'cfr', 'crf', 'csf', + 'sam') _dtype = "points" def __init__(self): From ecd0a9f87cb9cbc489e0edf77edcb216d941605b Mon Sep 17 00:00:00 2001 From: Chris Burbridge Date: Thu, 1 Oct 2015 11:15:29 +0100 Subject: [PATCH 4/8] Tidy up TPCC helper methods. --- qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py | 96 ++++++++++------------------- 1 file changed, 32 insertions(+), 64 deletions(-) diff --git a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py index 6fc5e4a..54d1f87 100644 --- a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py +++ b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py @@ -3,69 +3,6 @@ from qsrlib_qsrs.qsr_triadic_abstractclass import QSR_Triadic_1t_Abstractclass import math - -import sys -import math - -NUMBER_OF_PARTITIONS = 8 -PARTITION_SIZE = (2.0 * math.pi) / NUMBER_OF_PARTITIONS - -def relative_angle(a, b, c): - # compute relative angle (left/right/straight, front/back/straight) - angle_BA = math.atan2((b.y - a.y),(b.x - a.x)) - - if angle_BA < 0: - angle_BA += 2 * math.pi - - angle_CB = math.atan2((c.y - b.y), (c.x - b.x)) - if angle_CB < 0: - angle_CB += 2 * math.pi - - angle_rel = angle_CB - angle_BA - if angle_rel < 0: - angle_rel += 2 * math.pi - - return angle_rel - -def partition(angle): - return int(angle / PARTITION_SIZE) - -def partition_name(p): - if p == 0: - return 'bl' - elif p == 1: - return 'lb' - elif p == 2: - return 'lf' - elif p == 3: - return 'fl' - elif p == 4: - return 'fr' - elif p == 5: - return 'rf' - elif p == 6: - return 'rb' - else: # p ==7 - return 'br' - - -def calc_TPCC(origin, relatum, objct): - - base_distance = math.sqrt((origin.x-relatum.x)**2 + (origin.y-relatum.y)**2) - object_distance = math.sqrt((objct.x-relatum.x)**2 + (objct.y-relatum.y)**2) - if base_distance == object_distance: - return "sam" - - relation = "d" if object_distance > base_distance else "c" # is it far or close: first letter - - rela = relative_angle(origin, relatum, objct) - - part = partition(rela) #TODO: the "*s*" relations - relation+=partition_name(part) - - return relation - - class QSR_TPCC(QSR_Triadic_1t_Abstractclass): """ TPCC QSRs. .. seealso:: For further details about TPCC, see http://www.sfbtr8.spatial-cognition.de/project/r3/QualitativeCalculi/TPCC/index.html. @@ -76,10 +13,41 @@ class QSR_TPCC(QSR_Triadic_1t_Abstractclass): 'clb', 'csb', 'crb', 'cbr', 'csr', 'cfr', 'crf', 'csf', 'sam') _dtype = "points" + __partition_names = ['bl','lb','lf','fl','fr','rf','rb','br'] def __init__(self): """Constructor.""" super(QSR_TPCC, self).__init__() def _compute_qsr(self, origin, relatum, objct, qsr_params, **kwargs): - return calc_TPCC(origin, relatum, objct) + base_distance = math.sqrt((origin.x-relatum.x)**2 + (origin.y-relatum.y)**2) + object_distance = math.sqrt((objct.x-relatum.x)**2 + (objct.y-relatum.y)**2) + if base_distance == object_distance: + return "sam" + + relation = "d" if object_distance > base_distance else "c" # is it far or close: first letter + + angle = self._relative_angle(origin, relatum, objct) + partition = int(angle / 8) #TODO: the "*s*" relations + relation += self.__partition_names[partition] + + return relation + + @staticmethod + def _relative_angle(a, b, c): + """Compute relative angle used to select the (left/right/straight/front/back/straight) + relationship""" + angle_BA = math.atan2((b.y - a.y),(b.x - a.x)) + + if angle_BA < 0: + angle_BA += 2 * math.pi + + angle_CB = math.atan2((c.y - b.y), (c.x - b.x)) + if angle_CB < 0: + angle_CB += 2 * math.pi + + angle_rel = angle_CB - angle_BA + if angle_rel < 0: + angle_rel += 2 * math.pi + + return angle_rel From 37d147e6596121b5ac7bab73eb401739eb7fc8b6 Mon Sep 17 00:00:00 2001 From: Yiannis Gatsoulis Date: Thu, 1 Oct 2015 13:09:10 +0100 Subject: [PATCH 5/8] tidy up examples --- qsr_lib/scripts/example_extended.py | 14 ++++++++++++++ qsr_lib/scripts/mwe.py | 26 ++++++++++---------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/qsr_lib/scripts/example_extended.py b/qsr_lib/scripts/example_extended.py index 589e2a5..af780fe 100755 --- a/qsr_lib/scripts/example_extended.py +++ b/qsr_lib/scripts/example_extended.py @@ -69,6 +69,17 @@ def pretty_print_world_qsr_trace(which_qsr, qsrlib_response_message): world.add_object_state_series(o2) world.add_object_state_series(o3) + elif which_qsr == "tpcc": + # Then we need three objects to do a test... + # Don't bother with more than one timestamp. + o1 = [Object_State(name="o1", timestamp=0, x=0., y=0., xsize=5., ysize=8.)] + o2 = [Object_State(name="o2", timestamp=0, x=5., y=0., xsize=5., ysize=8.)] + o3 = [Object_State(name="o3", timestamp=0, x=5., y=0., xsize=5., ysize=8.)] + + world.add_object_state_series(o1) + world.add_object_state_series(o2) + world.add_object_state_series(o3) + elif which_qsr == "rcc8" or which_qsr == "rcc5": # dynamic_args = {which_qsr: {"quantisation_factor": args.quantisation_factor}} o1 = [Object_State(name="o1", timestamp=0, x=1., y=1., xsize=5., ysize=8.), @@ -315,6 +326,9 @@ def pretty_print_world_qsr_trace(which_qsr, qsrlib_response_message): # print(dynamic_args["for_all_qsrs"]["qsrs_for"]) # # DBG: eof + # dynamic_args[which_qsr]["qsrs_for"] = [("o1", "o2", "o3"), ("o1", "o3")] + dynamic_args = {"tpcc": {"qsrs_for": [("o1", "o2", "o3"), ("o1", "o3")]}} + qsrlib_request_message = QSRlib_Request_Message(which_qsr=which_qsr, input_data=world, dynamic_args=dynamic_args) if args.ros: diff --git a/qsr_lib/scripts/mwe.py b/qsr_lib/scripts/mwe.py index 49b5ee8..b926bbd 100755 --- a/qsr_lib/scripts/mwe.py +++ b/qsr_lib/scripts/mwe.py @@ -37,24 +37,18 @@ def pretty_print_world_qsr_trace(which_qsr, qsrlib_response_message): # **************************************************************************************************** # make some input data world = World_Trace() - if which_qsr == "tpcc": - # Then we need three objects to do a test... - # Don't bother with more than one timestamp. - o1 = [Object_State(name="o1", timestamp=0, x=2., y=4., xsize=5., ysize=8.)] - o2 = [Object_State(name="o2", timestamp=0, x=6., y=5., xsize=5., ysize=8.)] - o3 = [Object_State(name="o3", timestamp=0, x=5., y=2., xsize=5.2, ysize=8.5)] + o1 = [Object_State(name="o1", timestamp=0, x=1., y=1., xsize=5., ysize=8.), + Object_State(name="o1", timestamp=1, x=1., y=2., xsize=5., ysize=8.)] - world.add_object_state_series(o1) - world.add_object_state_series(o2) - world.add_object_state_series(o3) - else: - o1 = [Object_State(name="o1", timestamp=0, x=1., y=1., xsize=5., ysize=8.), - Object_State(name="o1", timestamp=1, x=1., y=2., xsize=5., ysize=8.)] + o2 = [Object_State(name="o2", timestamp=0, x=11., y=1., xsize=5., ysize=8.), + Object_State(name="o2", timestamp=1, x=1., y=2., xsize=5., ysize=8.)] + + o3 = [Object_State(name="o3", timestamp=0, x=5., y=2., xsize=5.2, ysize=8.5), + Object_State(name="o3", timestamp=1, x=6., y=4., xsize=5.2, ysize=8.5)] - o2 = [Object_State(name="o2", timestamp=0, x=11., y=1., xsize=5., ysize=8.), - Object_State(name="o2", timestamp=1, x=1., y=2., xsize=5., ysize=8.)] - world.add_object_state_series(o1) - world.add_object_state_series(o2) + world.add_object_state_series(o1) + world.add_object_state_series(o2) + world.add_object_state_series(o3) # **************************************************************************************************** # make a QSRlib request message From 291a3399fe63c200b21c4e56694e20d12e5d5ccd Mon Sep 17 00:00:00 2001 From: Chris Burbridge Date: Thu, 1 Oct 2015 13:40:20 +0100 Subject: [PATCH 6/8] Fix 'sam' relation. --- qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py index 54d1f87..b0c4327 100644 --- a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py +++ b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py @@ -22,7 +22,7 @@ def __init__(self): def _compute_qsr(self, origin, relatum, objct, qsr_params, **kwargs): base_distance = math.sqrt((origin.x-relatum.x)**2 + (origin.y-relatum.y)**2) object_distance = math.sqrt((objct.x-relatum.x)**2 + (objct.y-relatum.y)**2) - if base_distance == object_distance: + if object_distance == 0: return "sam" relation = "d" if object_distance > base_distance else "c" # is it far or close: first letter From 246790704d3b342d85f1f4aa59e39cf165132905 Mon Sep 17 00:00:00 2001 From: Chris Burbridge Date: Thu, 1 Oct 2015 14:16:16 +0100 Subject: [PATCH 7/8] Fix broken partitioning. --- qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py index b0c4327..78ae27a 100644 --- a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py +++ b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py @@ -14,6 +14,7 @@ class QSR_TPCC(QSR_Triadic_1t_Abstractclass): 'sam') _dtype = "points" __partition_names = ['bl','lb','lf','fl','fr','rf','rb','br'] + __partition_size = 2 * math.pi / len(__partition_names) def __init__(self): """Constructor.""" @@ -28,7 +29,7 @@ def _compute_qsr(self, origin, relatum, objct, qsr_params, **kwargs): relation = "d" if object_distance > base_distance else "c" # is it far or close: first letter angle = self._relative_angle(origin, relatum, objct) - partition = int(angle / 8) #TODO: the "*s*" relations + partition = int(angle / self.__partition_size) #TODO: the "*s*" relations relation += self.__partition_names[partition] return relation From 4bf210d11ef733ca31d87b265777c39880e52754 Mon Sep 17 00:00:00 2001 From: Chris Burbridge Date: Fri, 2 Oct 2015 11:38:16 +0100 Subject: [PATCH 8/8] Add *s* relation. --- qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py index 78ae27a..7c75943 100644 --- a/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py +++ b/qsr_lib/src/qsrlib_qsrs/qsr_tpcc.py @@ -13,7 +13,7 @@ class QSR_TPCC(QSR_Triadic_1t_Abstractclass): 'clb', 'csb', 'crb', 'cbr', 'csr', 'cfr', 'crf', 'csf', 'sam') _dtype = "points" - __partition_names = ['bl','lb','lf','fl','fr','rf','rb','br'] + __partition_names = ['lb','bl','fl','lf','rf','fr','br','rb'] __partition_size = 2 * math.pi / len(__partition_names) def __init__(self): @@ -29,8 +29,12 @@ def _compute_qsr(self, origin, relatum, objct, qsr_params, **kwargs): relation = "d" if object_distance > base_distance else "c" # is it far or close: first letter angle = self._relative_angle(origin, relatum, objct) - partition = int(angle / self.__partition_size) #TODO: the "*s*" relations + partition = int(angle / self.__partition_size) relation += self.__partition_names[partition] + + sin_angle = math.fabs(math.sin(angle)) + if sin_angle < 0.00001 or sin_angle > 0.99999: + relation = relation[0]+'s'+relation[2] return relation