예제 #1
0
class TrajectoryQueryService():
    def __init__(self):
        self.gs = GeoSpatialStoreProxy('geospatial_store', 'soma')
        self.ms = MessageStoreProxy(collection="people_trajectory")

        # setting up the service
        self.ser = rospy.Service('/trajectory_query', TrajectoryQuery,
                                 self.service_cb)
        self.topic = 'trajectory_query'
        self.vis = TrajectoryVisualizer(self.topic)

    def retrieve_msg(self, uuid):
        res = self.ms.query(Trajectory._type, message_query={"uuid": uuid})
        if len(res) < 1:
            rospy.logerr("Trajectory not found: %s" % uuid)
            return None
        elif len(res) > 1:
            rospy.logerr("Multiple trajectories found: %s" % uuid)
            t = res[0][0]
            return t

        t = res[0][0]
        return t

    def service_cb(self, req):
        rospy.loginfo("Request received: %s" % req)
        if req.visualize:
            self.vis.clear()

        res = TrajectoryQueryResponse()
        res.trajectories = Trajectories()
        try:
            json_query = json.loads(req.query)
            trajectories = self.gs.find(json_query)
        except:
            rospy.logerr("Invalid json => re-check syntax")
            res.error = True
            return res

        count = 0
        for t in trajectories:
            if t.has_key('uuid'):
                count += 1
                #rospy.loginfo("retrieve msg for uuid: %s" % t['uuid'])
                # otherwise result is not a trajectory => ignore
                msg = self.retrieve_msg(t['uuid'])
                if msg:
                    res.trajectories.trajectories.append(msg)

        rospy.loginfo("Query result: %s trajectories" % count)

        if req.visualize:
            rospy.loginfo("Visualize result on topic: %s" % self.topic)
            self.vis.visualize_trajectories(res.trajectories)
        rospy.loginfo("Response returned")
        res.error = False
        return res

    def main(self):
        rospy.spin()
예제 #2
0
class TrajectoryQueryService():

    def __init__(self):
        self.gs = GeoSpatialStoreProxy('geospatial_store','soma')
        self.ms = MessageStoreProxy(collection="people_trajectory")

        # setting up the service
        self.ser = rospy.Service('/trajectory_query', TrajectoryQuery, self.service_cb)
        self.topic = 'trajectory_query'
        self.vis = TrajectoryVisualizer(self.topic)

    def retrieve_msg(self, uuid):
        res = self.ms.query(Trajectory._type, message_query={"uuid": uuid})
        if len(res) < 1:
            rospy.logerr("Trajectory not found: %s" % uuid)
            return None
        elif len(res) > 1:
            rospy.logerr("Multiple trajectories found: %s" % uuid)
            t = res[0][0]
            return t

        t = res[0][0]
        return t

    def service_cb(self, req):
        rospy.loginfo("Request received: %s" % req)
        if req.visualize:
            self.vis.clear()

        res = TrajectoryQueryResponse()
        res.trajectories = Trajectories()
        try:
            json_query = json.loads(req.query)
            trajectories = self.gs.find(json_query)
        except:
            rospy.logerr("Invalid json => re-check syntax")
            res.error = True
            return res

        count = 0
        for t in trajectories:
            if t.has_key('uuid'):
                count += 1
                #rospy.loginfo("retrieve msg for uuid: %s" % t['uuid'])
                # otherwise result is not a trajectory => ignore
                msg = self.retrieve_msg(t['uuid'])
                if msg:
                    res.trajectories.trajectories.append(msg)

        rospy.loginfo("Query result: %s trajectories" % count)

        if req.visualize:
            rospy.loginfo("Visualize result on topic: %s" % self.topic)
            self.vis.visualize_trajectories(res.trajectories)
        rospy.loginfo("Response returned")
        res.error = False
        return res

    def main(self):
        rospy.spin()
class TrajectoryRegionEstimate(object):

    def __init__(self, soma_map, soma_config, minute_interval=60):
        self.soma_map = soma_map
        self.soma_config = soma_config
        self.minute_interval = minute_interval
        self.region_knowledge = RegionObservationTimeManager(soma_map, soma_config)
        # Service and Proxy
        rospy.loginfo("Connecting to geospatial_store and roslog database...")
        self.gs = GeoSpatialStoreProxy('geospatial_store', 'soma')

    def estimate_trajectories_daily(self, dates, month=1, year=2015):
        """
            Estimate the number of trajectories in a region hourly each day for particular dates
            assuming that the robot sees the complete region when it sees the region
        """
        days = [date for date in dates if date <= calendar.monthrange(year, month)[1]]
        days = [
            datetime.datetime(year, month, i, 0, 0) for i in days
        ]
        return self.estimate_trajectories(days)

    def estimate_trajectories(self, days):
        """
            Estimate the number of trajectories in a region for days,
            assuming that the robot sees the complete region when it sees the region
        """
        days_trajectories = dict()
        roi_region_daily = self.region_knowledge.calculate_region_observation_duration(
            days, self.minute_interval
        )
        trajectory_region_daily = self.obtain_number_of_trajectories(days)

        query = {
            "soma_map": self.soma_map, "soma_config": self.soma_config,
            "soma_roi_id": {"$exists": True}
        }
        regions = self.gs.find_projection(query, {"soma_roi_id": 1})
        minutes = [
            i * self.minute_interval for i in range(1, (60/self.minute_interval) + 1)
        ]
        for region in regions:
            reg = region['soma_roi_id']
            for day in days:
                day = day.day
                if not(day in roi_region_daily and day in trajectory_region_daily):
                    continue
                if reg not in days_trajectories:
                    days_trajectories[reg] = dict()
                if day not in days_trajectories[reg]:
                    temp = list()
                    for i in range(24):
                        temp.append({i: -1 for i in minutes})
                    days_trajectories[reg][day] = temp
                for hour in range(24):
                    for minute in minutes:
                        if reg in roi_region_daily[day]:
                            days_trajectories = self._estimate_trajectories_by_minutes(
                                reg, day, hour, minute, days_trajectories,
                                roi_region_daily[day], trajectory_region_daily[day]
                            )

        return days_trajectories

    def _extrapolate_trajectory_estimate(self, len_min_interval, seconds_stay_duration, num_traj):
        """ extrapolate the number of trajectories with specific upper_threshold.
            upper_threshold is to ceil how long the robot was in an area
            for one minute interval, if the robot was there for less than 20
            seconds, then it will be boosted to 20 seconds.
        """
        upper_threshold_duration = 0
        while seconds_stay_duration > upper_threshold_duration:
            upper_threshold_duration += self.minute_interval * 20

        multiplier_estimator = 3600 / float(
            len_min_interval * upper_threshold_duration
        )
        return math.ceil(multiplier_estimator * num_traj)

    def _hard_trajectory_estimate(self, seconds_stay_duration, num_traj):
        """ Estimating the number of trajectories with hard threshold.
            This forces the seconds_stay_duration to be 60 seconds for num_traj to be registered.
        """
        temp_num_traj = -1
        if seconds_stay_duration >= self.minute_interval * 60:
            temp_num_traj = num_traj
        return temp_num_traj

    def _estimate_trajectories_by_minutes(
        self, region, day, hour, minute, days_trajectories, rois_day, trajectories_day
    ):
        minutes = [
            i * self.minute_interval for i in range(1, (60/self.minute_interval) + 1)
        ]
        if len(trajectories_day) > hour:
            if region in trajectories_day[hour]:
                if minute in trajectories_day[hour][region]:
                    traj = trajectories_day[hour][region][minute]
                    if rois_day[region][hour][minute] > 0:
                        days_trajectories[region][day][hour][minute] = self._extrapolate_trajectory_estimate(
                            len(minutes), rois_day[region][hour][minute], traj
                        )
                        # days_trajectories[region][day][hour][minute] = self._hard_trajectory_estimate(
                        #     rois_day[region][hour][minute], traj
                        # )
                    else:
                        if traj > 0:
                            rospy.logwarn(
                                "%d trajectories are detected in region %s at day %d hour %d minute %d, but no info about robot being there" % (
                                    traj, region, day, hour, minute
                                )
                            )
                else:
                    if rois_day[region][hour][minute] >= self.minute_interval * 60:
                        days_trajectories[region][day][hour][minute] = 0
            else:
                for i in minutes:
                    if rois_day[region][hour][i] >= self.minute_interval * 60:
                        days_trajectories[region][day][hour][i] = 0
        else:
            query = {
                "soma_map": self.soma_map, "soma_config": self.soma_config,
                "soma_roi_id": {"$exists": True}
            }
            regions = self.gs.find_projection(query, {"soma_roi_id": 1})
            for j in regions:
                reg = j['soma_roi_id']
                if reg in rois_day and hour in rois_day[reg]:
                    for i in minutes:
                        if i in rois_day[reg][hour] and rois_day[reg][hour][i] >= self.minute_interval * 60:
                            days_trajectories[reg][day][hour][i] = 0

        return days_trajectories

    def obtain_number_of_trajectories(self, days):
        """
            Obtaining the number of trajectories for each day in argument days,
            The number of Trajectories will be split into day, hour, region, and minutes.
            Trajectories = [day[hour[region[minutes]]]]
        """
        rospy.loginfo('Updating frequency of trajectories in each region...')
        trajectory_region_daily = dict()
        for i in days:
            daily_trajectories = self._trajectories_daily(
                calendar.timegm(i.timetuple())
            )
            trajectory_region_daily.update({i.day: daily_trajectories})
        return trajectory_region_daily

    # count trajectories in regions for the whole day
    # day is in the epoch, so in default it refers to 1 Jan 1970
    def _trajectories_daily(self, day=0):
        daily_trajectories = list()
        for i in range(24):
            hourly_trajectories = self._trajectories_hourly_for_day(day, i)
            daily_trajectories.append(hourly_trajectories)
        return daily_trajectories

    # count trajectories in the region per hour for a certain day
    # day is in the epoch, so in default it refers to 1 Jan 1970
    def _trajectories_hourly_for_day(self, day=0, hour=0):
        date = datetime.date.fromtimestamp(day)
        rospy.loginfo(
            'Getting trajectories for day %s hour %d...' % (
                date.strftime("%d-%m-%Y"), hour
            )
        )
        start_hour = day + (hour * 3600)
        end_hour = day + ((hour + 1) * 3600)
        trajectories_hourly = self._get_num_traj_by_epoch(
            start_hour, end_hour, self.minute_interval*60
        )
        return trajectories_hourly

    def _get_num_traj_by_epoch(self, start, end, min_inter=3600):
        """
            Count the number of trajectories in areas defined by soma map and soma
            config that is restricted by the query.
        """
        start_hour = start
        end_hour = start + min_inter
        trajectories_hourly = dict()
        while end_hour <= end:
            query = {
                "$or": [
                    {"start": {"$gte": start_hour, "$lt": end_hour}},
                    {"end": {"$gte": start_hour, "$lt": end_hour}}
                ]
            }
            for geo_traj in self.gs.find(query):
                query = {
                    "soma_map":  self.soma_map,
                    "soma_config": self.soma_config,
                    "soma_roi_id": {"$exists": "true"},
                    "loc": {
                        "$geoIntersects": {
                            "$geometry": {
                                "type": "LineString",
                                "coordinates": geo_traj['loc']['coordinates']
                            }
                        }
                    }
                }
                roi_traj = self.gs.find_projection(query, {"soma_roi_id": 1})
                if roi_traj.count() < 1:
                    rospy.logwarn("No region covers the movement of uuid %s" % (geo_traj["uuid"]))
                else:
                    for region in roi_traj:
                        if region['soma_roi_id'] not in trajectories_hourly:
                            trajectories_hourly[region['soma_roi_id']] = dict()
                        index = (end_hour - start) / 60
                        if index not in trajectories_hourly[region['soma_roi_id']]:
                            trajectories_hourly[region['soma_roi_id']][index] = 0
                        trajectories_hourly[region['soma_roi_id']][index] += 1
            start_hour += min_inter
            end_hour += min_inter

        return trajectories_hourly
예제 #4
0
class TrajectoryRegionEstimate(object):
    def __init__(self, soma_map, soma_config, minute_interval=60):
        self.soma_map = soma_map
        self.soma_config = soma_config
        self.minute_interval = minute_interval
        self.region_knowledge = RegionObservationTimeManager(
            soma_map, soma_config)
        # Service and Proxy
        rospy.loginfo("Connecting to geospatial_store and roslog database...")
        self.gs = GeoSpatialStoreProxy('geospatial_store', 'soma')

    def estimate_trajectories_daily(self, dates, month=1, year=2015):
        """
            Estimate the number of trajectories in a region hourly each day for particular dates
            assuming that the robot sees the complete region when it sees the region
        """
        days = [
            date for date in dates
            if date <= calendar.monthrange(year, month)[1]
        ]
        days = [datetime.datetime(year, month, i, 0, 0) for i in days]
        return self.estimate_trajectories(days)

    def estimate_trajectories(self, days):
        """
            Estimate the number of trajectories in a region for days,
            assuming that the robot sees the complete region when it sees the region
        """
        days_trajectories = dict()
        roi_region_daily = self.region_knowledge.calculate_region_observation_duration(
            days, self.minute_interval)
        trajectory_region_daily = self.obtain_number_of_trajectories(days)

        query = {
            "soma_map": self.soma_map,
            "soma_config": self.soma_config,
            "soma_roi_id": {
                "$exists": True
            }
        }
        regions = self.gs.find_projection(query, {"soma_roi_id": 1})
        minutes = [
            i * self.minute_interval
            for i in range(1, (60 / self.minute_interval) + 1)
        ]
        for region in regions:
            reg = region['soma_roi_id']
            for day in days:
                day = day.day
                if not (day in roi_region_daily
                        and day in trajectory_region_daily):
                    continue
                if reg not in days_trajectories:
                    days_trajectories[reg] = dict()
                if day not in days_trajectories[reg]:
                    temp = list()
                    for i in range(24):
                        temp.append({i: -1 for i in minutes})
                    days_trajectories[reg][day] = temp
                for hour in range(24):
                    for minute in minutes:
                        if reg in roi_region_daily[day]:
                            days_trajectories = self._estimate_trajectories_by_minutes(
                                reg, day, hour, minute, days_trajectories,
                                roi_region_daily[day],
                                trajectory_region_daily[day])

        return days_trajectories

    def _extrapolate_trajectory_estimate(self, len_min_interval,
                                         seconds_stay_duration, num_traj):
        """ extrapolate the number of trajectories with specific upper_threshold.
            upper_threshold is to ceil how long the robot was in an area
            for one minute interval, if the robot was there for less than 20
            seconds, then it will be boosted to 20 seconds.
        """
        upper_threshold_duration = 0
        while seconds_stay_duration > upper_threshold_duration:
            upper_threshold_duration += self.minute_interval * 20

        multiplier_estimator = 3600 / float(
            len_min_interval * upper_threshold_duration)
        return math.ceil(multiplier_estimator * num_traj)

    def _hard_trajectory_estimate(self, seconds_stay_duration, num_traj):
        """ Estimating the number of trajectories with hard threshold.
            This forces the seconds_stay_duration to be 60 seconds for num_traj to be registered.
        """
        temp_num_traj = -1
        if seconds_stay_duration >= self.minute_interval * 60:
            temp_num_traj = num_traj
        return temp_num_traj

    def _estimate_trajectories_by_minutes(self, region, day, hour, minute,
                                          days_trajectories, rois_day,
                                          trajectories_day):
        minutes = [
            i * self.minute_interval
            for i in range(1, (60 / self.minute_interval) + 1)
        ]
        if len(trajectories_day) > hour:
            if region in trajectories_day[hour]:
                if minute in trajectories_day[hour][region]:
                    traj = trajectories_day[hour][region][minute]
                    if rois_day[region][hour][minute] > 0:
                        days_trajectories[region][day][hour][
                            minute] = self._extrapolate_trajectory_estimate(
                                len(minutes), rois_day[region][hour][minute],
                                traj)
                        # days_trajectories[region][day][hour][minute] = self._hard_trajectory_estimate(
                        #     rois_day[region][hour][minute], traj
                        # )
                    else:
                        if traj > 0:
                            rospy.logwarn(
                                "%d trajectories are detected in region %s at day %d hour %d minute %d, but no info about robot being there"
                                % (traj, region, day, hour, minute))
                else:
                    if rois_day[region][hour][
                            minute] >= self.minute_interval * 60:
                        days_trajectories[region][day][hour][minute] = 0
            else:
                for i in minutes:
                    if rois_day[region][hour][i] >= self.minute_interval * 60:
                        days_trajectories[region][day][hour][i] = 0
        else:
            query = {
                "soma_map": self.soma_map,
                "soma_config": self.soma_config,
                "soma_roi_id": {
                    "$exists": True
                }
            }
            regions = self.gs.find_projection(query, {"soma_roi_id": 1})
            for j in regions:
                reg = j['soma_roi_id']
                if reg in rois_day and hour in rois_day[reg]:
                    for i in minutes:
                        if i in rois_day[reg][hour] and rois_day[reg][hour][
                                i] >= self.minute_interval * 60:
                            days_trajectories[reg][day][hour][i] = 0

        return days_trajectories

    def obtain_number_of_trajectories(self, days):
        """
            Obtaining the number of trajectories for each day in argument days,
            The number of Trajectories will be split into day, hour, region, and minutes.
            Trajectories = [day[hour[region[minutes]]]]
        """
        rospy.loginfo('Updating frequency of trajectories in each region...')
        trajectory_region_daily = dict()
        for i in days:
            daily_trajectories = self._trajectories_daily(
                calendar.timegm(i.timetuple()))
            trajectory_region_daily.update({i.day: daily_trajectories})
        return trajectory_region_daily

    # count trajectories in regions for the whole day
    # day is in the epoch, so in default it refers to 1 Jan 1970
    def _trajectories_daily(self, day=0):
        daily_trajectories = list()
        for i in range(24):
            hourly_trajectories = self._trajectories_hourly_for_day(day, i)
            daily_trajectories.append(hourly_trajectories)
        return daily_trajectories

    # count trajectories in the region per hour for a certain day
    # day is in the epoch, so in default it refers to 1 Jan 1970
    def _trajectories_hourly_for_day(self, day=0, hour=0):
        date = datetime.date.fromtimestamp(day)
        rospy.loginfo('Getting trajectories for day %s hour %d...' %
                      (date.strftime("%d-%m-%Y"), hour))
        start_hour = day + (hour * 3600)
        end_hour = day + ((hour + 1) * 3600)
        trajectories_hourly = self._get_num_traj_by_epoch(
            start_hour, end_hour, self.minute_interval * 60)
        return trajectories_hourly

    def _get_num_traj_by_epoch(self, start, end, min_inter=3600):
        """
            Count the number of trajectories in areas defined by soma map and soma
            config that is restricted by the query.
        """
        start_hour = start
        end_hour = start + min_inter
        trajectories_hourly = dict()
        while end_hour <= end:
            query = {
                "$or": [{
                    "start": {
                        "$gte": start_hour,
                        "$lt": end_hour
                    }
                }, {
                    "end": {
                        "$gte": start_hour,
                        "$lt": end_hour
                    }
                }]
            }
            for geo_traj in self.gs.find(query):
                query = {
                    "soma_map": self.soma_map,
                    "soma_config": self.soma_config,
                    "soma_roi_id": {
                        "$exists": "true"
                    },
                    "loc": {
                        "$geoIntersects": {
                            "$geometry": {
                                "type": "LineString",
                                "coordinates": geo_traj['loc']['coordinates']
                            }
                        }
                    }
                }
                roi_traj = self.gs.find_projection(query, {"soma_roi_id": 1})
                if roi_traj.count() < 1:
                    rospy.logwarn("No region covers the movement of uuid %s" %
                                  (geo_traj["uuid"]))
                else:
                    for region in roi_traj:
                        if region['soma_roi_id'] not in trajectories_hourly:
                            trajectories_hourly[region['soma_roi_id']] = dict()
                        index = (end_hour - start) / 60
                        if index not in trajectories_hourly[
                                region['soma_roi_id']]:
                            trajectories_hourly[
                                region['soma_roi_id']][index] = 0
                        trajectories_hourly[region['soma_roi_id']][index] += 1
            start_hour += min_inter
            end_hour += min_inter

        return trajectories_hourly