mobility.swarmie module
Common rover interface in Python
''' Common rover interface in Python ''' from __future__ import print_function import sys import rospy import math import random import angles import tf from mobility.srv import Core from mapping.srv import FindTarget, GetMap from mobility.msg import MoveResult, MoveRequest from swarmie_msgs.msg import Obstacle from std_srvs.srv import Empty from std_msgs.msg import UInt8, String, Float32 from nav_msgs.msg import Odometry from geometry_msgs.msg import Point, Twist, Pose2D from apriltags_ros.msg import AprilTagDetectionArray from rospy.numpy_msg import numpy_msg from grid_map_msgs.msg import GridMap from mapping import RoverMap import threading swarmie_lock = threading.Lock() from mobility import sync class DriveException(Exception): def __init__(self, st): self.status = st class VisionException(DriveException): pass class TagException(VisionException): pass class HomeException(VisionException): pass class ObstacleException(DriveException): pass class PathException(DriveException): pass class AbortException(DriveException): pass class TimeoutException(DriveException): pass class Location: '''A class that encodes an EKF provided location and accessor methods''' def __init__(self, odo): self.Odometry = odo def get_pose(self): '''Return a std_msgs.Pose from this Location. Useful because Pose has angles represented as roll, pitch, yaw. Returns: * (`std_msgs.msg.Pose`) The pose. ''' quat = [self.Odometry.pose.pose.orientation.x, self.Odometry.pose.pose.orientation.y, self.Odometry.pose.pose.orientation.z, self.Odometry.pose.pose.orientation.w, ] (r, p, y) = tf.transformations.euler_from_quaternion(quat) pose = Pose2D() pose.x = self.Odometry.pose.pose.position.x pose.y = self.Odometry.pose.pose.position.y pose.theta = y return pose def at_goal(self, goal, distance): '''Determine if the pose is within acceptable distance of this location Returns: * (`bool`) True if within the target distance. ''' dist = math.hypot(goal.x - self.Odometry.pose.pose.position.x, goal.y - self.Odometry.pose.pose.position.y) return dist < distance def get_variances(self): '''Return the X, Y and Z variances from the covariance matrix of this location. Variance is defined as the expectation of the squared deviation of a random variable from its mean. https://en.wikipedia.org/wiki/Variance Returns: * (`tuple`): `(vX, vY, vZ)` ''' return (self.Odometry.pose.covariance[0:15:7]) class Swarmie: '''Class that embodies the Swarmie's API This is the Python API used to drive the rover. The API interfaces with ROS topics and services to perform action and acquire sensor data. ''' def __init__(self, rover, **kwargs): '''Constructor. Args: * `rover` (`string`) - Name of the rover. Keyword arguments: * `node_suffix` (`string`) - Optional argument to start up this node without killing the main /rover_CONTROLLER node. Used by teleop_keyboard ''' self.rover_name = rover self.Obstacles = 0 self.MapLocation = Location(None) self.OdomLocation = Location(None) self.Targets = AprilTagDetectionArray() # Intialize this ROS node. if 'node_suffix' in kwargs and kwargs['node_suffix']: rospy.init_node(rover + '_CONTROLLER' + kwargs['node_suffix']) else: rospy.init_node(rover + '_CONTROLLER') # Create publishiers. self.sm_publisher = rospy.Publisher(rover + '/state_machine', String, queue_size=10, latch=True) self.status_publisher = rospy.Publisher(rover + '/status', String, queue_size=10, latch=True) self.info_publisher = rospy.Publisher('/infoLog', String, queue_size=10, latch=True) self.mode_publisher = rospy.Publisher(rover + '/mode', UInt8, queue_size=1, latch=True) self.finger_publisher = rospy.Publisher(rover + '/fingerAngle/cmd', Float32, queue_size=1, latch=True) self.wrist_publisher = rospy.Publisher(rover + '/wristAngle/cmd', Float32, queue_size=1, latch=True) # Wait for necessary services to be online. # Services are APIs calls to other neodes. rospy.wait_for_service(rover + '/control') rospy.wait_for_service(rover + '/map/find_nearest_target') rospy.wait_for_service(rover + '/map/get_obstacle_map') rospy.wait_for_service(rover + '/map/get_target_map') # Numpy-ify the GridMap GetMap._response_class = rospy.numpy_msg.numpy_msg(GridMap) # Connect to services. self.control = rospy.ServiceProxy(rover + '/control', Core) self._find_nearest_target = rospy.ServiceProxy(rover + '/map/find_nearest_target', FindTarget) self._get_obstacle_map = rospy.ServiceProxy(rover + '/map/get_obstacle_map', GetMap) self._get_target_map = rospy.ServiceProxy(rover + '/map/get_target_map', GetMap) self._start_magnetometer_calibration = rospy.ServiceProxy(rover + '/start_magnetometer_calibration', Empty) self._store_magnetometer_calibration = rospy.ServiceProxy(rover + '/store_magnetometer_calibration', Empty) # Subscribe to useful topics rospy.Subscriber(rover + '/odom/filtered', Odometry, self._odom) rospy.Subscriber(rover + '/odom/ekf', Odometry, self._map) rospy.Subscriber(rover + '/obstacle', Obstacle, self._obstacle) rospy.Subscriber(rover + '/targets', AprilTagDetectionArray, self._targets) # Transform listener. Use this to transform between coordinate spaces. self.xform = tf.TransformListener() # Wait for sensors and tf to have data (this sucks) rospy.sleep(1) print ('Welcome', self.rover_name, 'to the world of the future.') @sync(swarmie_lock) def _odom(self, msg) : self.OdomLocation.Odometry = msg @sync(swarmie_lock) def _map(self, msg) : self.MapLocation.Odometry = msg @sync(swarmie_lock) def _obstacle(self, msg) : self.Obstacles &= ~msg.mask self.Obstacles |= msg.msg @sync(swarmie_lock) def _targets(self, msg) : self.Targets = msg def __drive(self, request, **kwargs): request.obstacles = ~0 if 'ignore' in kwargs : request.obstacles = ~kwargs['ignore'] request.timeout = 120 if 'timeout' in kwargs : request.timeout = kwargs['timeout'] value = self.control([request]).result.result if 'throw' not in kwargs or kwargs['throw'] : if value == MoveResult.OBSTACLE_SONAR : raise ObstacleException(value) elif value == MoveResult.OBSTACLE_TAG : raise TagException(value) elif value == MoveResult.OBSTACLE_HOME : raise HomeException(value) elif value == MoveResult.PATH_FAIL : raise PathException(value) elif value == MoveResult.USER_ABORT : raise AbortException(value) elif value == MoveResult.TIMEOUT : raise TimeoutException(value) return value def stop(self): '''Stop the rover by placing it in manual mode.''' msg = UInt8() msg.data = 1 self.mode_publisher.publish(msg) def go(self): '''Start the rover by placing it into autonomous mode.''' msg = UInt8() msg.data = 2 self.mode_publisher.publish(msg) def circle(self, **kwargs): '''Drive in a small circle Args: * See keyword arguments for drive commands Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' if random.randint(0,1) == 0 : return self.timed_drive(15, 0.1, 0.62, **kwargs) else: return self.timed_drive(15, 0.1, -0.62, **kwargs) def timed_drive(self, time, linear, angular, **kwargs): '''Send the specified velocity command for a given period of time. Args: * time (float) The duration of the timed command. * linear (float) The linear velocity of the rover (m/s) * angular (float) The angular velocity of the rover (radians/s) SEE: Keyword Arguments for drive commands Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' req = MoveRequest( timer=time, linear=linear, angular=angular, ) return self.__drive(req, **kwargs) def drive(self, distance, **kwargs): '''Drive the specfied distance Args: * `distance` (`float`) Meters to drive. Keyword arguments: * `ignore` (`int`) - Bitmask with Obstacle messages that will be ignored while driving. * `throw` (`bool`) - Raise a DriveException if an obstacle is encountered (default True). * `timeout` (`int`) - The command will fail after this number of seconds (defulat: 120) Returns: * If `throw=False` was given returns a `mobility_msgs.msg.MoveResult` containing an integer. \ Values are described in `src/mobility/msg/MoveResult.msg` * If `throw=True` (the default) is given the return value will be converted into an exception. \ The following exceptions are defined: * `mobility.swarmie.DriveException` - Base class for driving exceptions. * `mobility.swarmie.VisionException` - Base class for exceptions caused by seeing a tag * `mobility.swarmie.TagException` - Exception caused when the target tag (0) is seen. * `mobility.swarmie.HomeException` - Exception caused when the home tag (256) is seen. * `mobility.swarmie.ObstacleException` - Exception caused when sonar senses the rover \ is close to an obstacle. * `mobility.swarmie.PathException` - Exception caused when the rover encounters an \ error while driving. If the rover detects a large angle between itself and its goal this \ happens. It's usually because the rover has driven over some kind of obstacle. * `mobility.swarmie.AbortException` - Exception caused when the user places the rover into \ manual mode while it was driving. * `mobility.swarmie.TimeoutException` - Exception caused when the drive command fails to \ complete in the amount of time specified with the `timeout=` argument. ''' req = MoveRequest( r=distance, ) return self.__drive(req, **kwargs) def turn(self, theta, **kwargs): '''Turn theta degrees Args: * `theta` (float) Radians to turn Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' req = MoveRequest( theta=theta, ) return self.__drive(req, **kwargs) def wait(self, time, **kwargs): '''Wait for a period of time. This can be used to check for obstacles Args: * `time` (`float`) seconds to wait. Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' req = MoveRequest( timer=time, ) return self.__drive(req, **kwargs) def set_wrist_angle(self, angle): '''Set the wrist angle to the specified angle Args: * `angle` (`float`) Wrist angle in radians. ''' self.wrist_publisher.publish(Float32(angle)) def set_finger_angle(self, angle): '''Set the finger angle to the spedified angle Args: * `angle` (`float`) Finger angle in radians. ''' self.finger_publisher.publish(Float32(angle)) def wrist_down(self): '''Lower the wrist to put it in the pickup position''' self.wrist_publisher.publish(Float32(1.25)) def wrist_up(self): '''Raise the wrist to the top''' self.wrist_publisher.publish(Float32(0.0)) def wrist_middle(self): '''Put the wrist in the middle of its travel so that the rover can drive with a block''' self.wrist_publisher.publish(Float32(0.75)) def fingers_open(self): '''Open the fingers''' self.finger_publisher.publish(Float32(math.pi/2)) def fingers_close(self): '''Close the fingers''' self.finger_publisher.publish(Float32(0.0)) def print_state_machine(self, msg): '''Print a message to the /rover/state_machine topic.''' s = String() s.data = msg self.sm_publisher.publish(s) def print_infoLog(self, msg): '''Print a message to the /infoLog topic this is viewable in the GUI''' s = String() s.data = msg self.info_publisher.publish(s) def print_status(self, msg): '''Print a message to the /rover/status topic this is viewable in the GUI''' s = String() s.data = msg self.status_publisher.publish(s) def has_block(self): '''Try to determine if a block is in our grasp. Uses the algorithm: * Raise the wrist all the way up. * Check if the center sonar is blocked at a close distance. If so, return `True` * Check if we can see a block that's very close. If so, return `True` * Check if this is the simulator. If so, return `True` * Return `False` ''' self.wrist_up() rospy.sleep(2) # First test: is something blocking the center sonar at a short range. obstacles = self.get_obstacle_condition() if obstacles & Obstacle.SONAR_BLOCK : return True # Second test: Can we see a bock that's close to the camera. blocks = self.get_latest_targets() blocks = sorted(blocks.detections, key=lambda x : abs(x.pose.pose.position.x)) if len(blocks) == 0 : return False nearest = blocks[0] x_dist = nearest.pose.pose.position.x if abs(x_dist) < 0.1 : return True # Third test: The block never seems to affect the sonar in the simulator. # Also, the grasped block rarely seems to be recognized in the simulator. # Which is whack. return(self.simulator_running()) def simulator_running(self): '''Helper Returns True if there is a /gazebo/link_states topic otherwise False''' for t in rospy.get_published_topics(): if t[0] == '/gazebo/link_states' : # This is the simulator return True return False def pickup(self): '''Picks up the block''' finger_close_angle = .5 if self.simulator_running(): finger_close_angle = 0 self.set_finger_angle(2) #open rospy.sleep(1) self.set_wrist_angle(1) rospy.sleep(.7) self.set_finger_angle(finger_close_angle) #close rospy.sleep(1) self.wrist_up() return(self.has_block()) def putdown(self): '''Puts the block down''' self.set_wrist_angle(1) rospy.sleep(.7) self.set_finger_angle(2) #open rospy.sleep(1) self.wrist_up() def find_nearest_target(self) : '''Broken: Return a XXX that is the odom location of the nearest target on the map.''' return self._find_nearest_target() def get_latest_targets(self) : '''Return the latest `apriltags_ros.msg.ArpilTagDetectionArray`. (it might be out of date)''' return self.Targets def get_obstacle_map(self): '''Return a `mapping.msg.RoverMap` that is the obstacle map. See `./src/mapping/src/mapping/__init__.py` for documentation of RoverMap''' return RoverMap(self._get_obstacle_map()) def get_target_map(self): '''Return a `mapping.msg.RoverMap` that is the targets map. See `./src/mapping/src/mapping/__init__.py` for documentation of RoverMap''' return RoverMap(self._get_target_map()) def start_magnetometer_calibration(self): '''Start calibrating the magnetometer on a rover.''' self._start_magnetometer_calibration() def store_magnetometer_calibration(self): '''Finish calibrating the magnetometer on a rover.''' self._store_magnetometer_calibration() def get_odom_location(self): '''Returns a `mobility.swarmie.Location` according to Odometery. This location will not jump arround and is locally accurate but will drift over time.''' with swarmie_lock : return self.OdomLocation def get_gps_location(self): '''Returns a `mobility.swarmie.Location` that is the output of the EKF that fuses GPS. This value has varying accuracy. The accuracy is reported in a covariance matrix. If you want to wait for a __good__ reading use `mobility.swarmie.Swarmie.wait_for_fix`''' with swarmie_lock : return self.MapLocation def wait_for_fix(self, distance=4, time=30): '''Wait until the GPS fix is reasonably accurate. This could take a while! Arguments: * `distance`: (`float`) The desired accuracty (+/- distance meters) with a likelyhood \ of 50%. Defaults to 4 meters. * `time`: (`int`) The number of seconds to wait for a good GPS measurement before giving up. \ Defaults to 30 seconds. Returns: * A `mobility.swarmie.Location` if the fix was successful. None if we waited until the timeout. ''' for i in xrange(time) : rospy.sleep(1) loc = self.get_gps_location() vx, vy, vz = loc.get_variances() if math.sqrt(vy) < distance : return loc return None def get_obstacle_condition(self): '''Returns the current obstacle condition. The presence of obstacles is indicated by bits in the returned integer. The definition of the bits can be found in `src/swarmie_msgs/msg/Obstacle.msg` Bit definitions: bit 1: SONAR_LEFT bit 2: SONAR_RIGHT bit 3: SONAR_CENTER bit 4: SONAR_BLOCK bit 8: TAG_TARGET bit 9: TAG_HOME Bit masks: IS_SONAR = SONAR_LEFT | SONAR_CENTER | SONAR_RIGHT | SONAR_BLOCK IS_VISION = TAG_TARGET | TAG_HOME ''' with swarmie_lock : return self.Obstacles def set_home_gps_location(self, loc): '''Remember the home GPS location reading. The location can be recalled by other control programs. Arguments: * loc: (`mobility.swarmie.Location`) The GPS coordinates to remember. ''' rospy.set_param('/' + self.rover_name + '/home_gps', {'x' : loc.Odometry.pose.pose.position.x, 'y' : loc.Odometry.pose.pose.position.y}) def get_home_gps_location(self): '''Recall the home GPS location. Returns: * (`geometry_msgs.msg.Point`) : The location of home. ''' return Point(**rospy.get_param('/' + self.rover_name + '/home_gps', {'x' : 0, 'y' : 0})) def has_home_gps_location(self): '''Check to see if the home location parameter is set. Returns: * (`bool`): True if the parameter exists, False otherwise. ''' return rospy.has_param('/' + self.rover_name + '/home_gps') def set_home_odom_location(self, loc): '''Remember the home odometry location. The location can be recalled by other control programs. Set this every time we see the nest to minimize the effect of drift. Arguments: * loc: (`mobility.swarmie.Location`) The coordinates to remember. ''' rospy.set_param('/' + self.rover_name + '/home_odom', {'x' : loc.Odometry.pose.pose.position.x, 'y' : loc.Odometry.pose.pose.position.y}) def get_home_odom_location(self): '''Recall the home odometry location. This is probably the most reliable memory of the location of the nest. Odometry drifts, so if we haven't seen home in a while this will be off. Returns: * (`geometry_msgs.msg.Point`) : The location of home. ''' return Point(**rospy.get_param('/' + self.rover_name + '/home_odom', {'x' : 0, 'y' : 0})) def has_home_odom_location(self): '''Check to see if the home odometry location parameter is set. Returns: * (`bool`): `True` if the parameter exists, `False` otherwise. ''' return rospy.has_param('/' + self.rover_name + '/home_odom') def drive_to(self, place, **kwargs): '''Drive directly to a particular point in space. The point must be in the odometry reference frame. Arguments: * `place`: (`geometry_msgs.msg.Point`): The place to drive. Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' loc = self.get_odom_location().get_pose() dist = math.hypot(loc.y - place.y, loc.x - place.x) angle = angles.shortest_angular_distance(loc.theta, math.atan2(place.y - loc.y, place.x - loc.x)) self.turn(angle, **kwargs) self.drive(dist, **kwargs) def set_heading(self, heading, **kwargs): '''Turn to face an absolute heading in radians. (zero is east) Arguments: * `heading`: (`float`) The heading in radians. Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' loc = self.get_odom_location().get_pose() angle = angles.shortest_angular_distance(loc.theta, heading) self.turn(angle, **kwargs)
Module variables
var swarmie_lock
Classes
class AbortException
class AbortException(DriveException): pass
Ancestors (in MRO)
- AbortException
- DriveException
- exceptions.Exception
- exceptions.BaseException
- __builtin__.object
Class variables
Instance variables
Methods
def __init__(
self, st)
Inheritance:
DriveException
.__init__
def __init__(self, st): self.status = st
class DriveException
class DriveException(Exception): def __init__(self, st): self.status = st
Ancestors (in MRO)
- DriveException
- exceptions.Exception
- exceptions.BaseException
- __builtin__.object
Class variables
var args
var message
Instance variables
var status
Methods
def __init__(
self, st)
def __init__(self, st): self.status = st
class HomeException
class HomeException(VisionException): pass
Ancestors (in MRO)
- HomeException
- VisionException
- DriveException
- exceptions.Exception
- exceptions.BaseException
- __builtin__.object
Class variables
Instance variables
Methods
def __init__(
self, st)
Inheritance:
VisionException
.__init__
def __init__(self, st): self.status = st
class Location
A class that encodes an EKF provided location and accessor methods
class Location: '''A class that encodes an EKF provided location and accessor methods''' def __init__(self, odo): self.Odometry = odo def get_pose(self): '''Return a std_msgs.Pose from this Location. Useful because Pose has angles represented as roll, pitch, yaw. Returns: * (`std_msgs.msg.Pose`) The pose. ''' quat = [self.Odometry.pose.pose.orientation.x, self.Odometry.pose.pose.orientation.y, self.Odometry.pose.pose.orientation.z, self.Odometry.pose.pose.orientation.w, ] (r, p, y) = tf.transformations.euler_from_quaternion(quat) pose = Pose2D() pose.x = self.Odometry.pose.pose.position.x pose.y = self.Odometry.pose.pose.position.y pose.theta = y return pose def at_goal(self, goal, distance): '''Determine if the pose is within acceptable distance of this location Returns: * (`bool`) True if within the target distance. ''' dist = math.hypot(goal.x - self.Odometry.pose.pose.position.x, goal.y - self.Odometry.pose.pose.position.y) return dist < distance def get_variances(self): '''Return the X, Y and Z variances from the covariance matrix of this location. Variance is defined as the expectation of the squared deviation of a random variable from its mean. https://en.wikipedia.org/wiki/Variance Returns: * (`tuple`): `(vX, vY, vZ)` ''' return (self.Odometry.pose.covariance[0:15:7])
Ancestors (in MRO)
Instance variables
var Odometry
Methods
def __init__(
self, odo)
def __init__(self, odo): self.Odometry = odo
def at_goal(
self, goal, distance)
Determine if the pose is within acceptable distance of this location
Returns:
- (
bool
) True if within the target distance.
def at_goal(self, goal, distance): '''Determine if the pose is within acceptable distance of this location Returns: * (`bool`) True if within the target distance. ''' dist = math.hypot(goal.x - self.Odometry.pose.pose.position.x, goal.y - self.Odometry.pose.pose.position.y) return dist < distance
def get_pose(
self)
Return a std_msgs.Pose from this Location. Useful because Pose has angles represented as roll, pitch, yaw.
Returns:
- (
std_msgs.msg.Pose
) The pose.
def get_pose(self): '''Return a std_msgs.Pose from this Location. Useful because Pose has angles represented as roll, pitch, yaw. Returns: * (`std_msgs.msg.Pose`) The pose. ''' quat = [self.Odometry.pose.pose.orientation.x, self.Odometry.pose.pose.orientation.y, self.Odometry.pose.pose.orientation.z, self.Odometry.pose.pose.orientation.w, ] (r, p, y) = tf.transformations.euler_from_quaternion(quat) pose = Pose2D() pose.x = self.Odometry.pose.pose.position.x pose.y = self.Odometry.pose.pose.position.y pose.theta = y return pose
def get_variances(
self)
Return the X, Y and Z variances from the covariance matrix of this location. Variance is defined as the expectation of the squared deviation of a random variable from its mean.
https://en.wikipedia.org/wiki/Variance
Returns:
- (
tuple
):(vX, vY, vZ)
def get_variances(self): '''Return the X, Y and Z variances from the covariance matrix of this location. Variance is defined as the expectation of the squared deviation of a random variable from its mean. https://en.wikipedia.org/wiki/Variance Returns: * (`tuple`): `(vX, vY, vZ)` ''' return (self.Odometry.pose.covariance[0:15:7])
class ObstacleException
class ObstacleException(DriveException): pass
Ancestors (in MRO)
- ObstacleException
- DriveException
- exceptions.Exception
- exceptions.BaseException
- __builtin__.object
Class variables
Instance variables
Methods
def __init__(
self, st)
Inheritance:
DriveException
.__init__
def __init__(self, st): self.status = st
class PathException
class PathException(DriveException): pass
Ancestors (in MRO)
- PathException
- DriveException
- exceptions.Exception
- exceptions.BaseException
- __builtin__.object
Class variables
Instance variables
Methods
def __init__(
self, st)
Inheritance:
DriveException
.__init__
def __init__(self, st): self.status = st
class Swarmie
Class that embodies the Swarmie's API
This is the Python API used to drive the rover. The API interfaces with ROS topics and services to perform action and acquire sensor data.
class Swarmie: '''Class that embodies the Swarmie's API This is the Python API used to drive the rover. The API interfaces with ROS topics and services to perform action and acquire sensor data. ''' def __init__(self, rover, **kwargs): '''Constructor. Args: * `rover` (`string`) - Name of the rover. Keyword arguments: * `node_suffix` (`string`) - Optional argument to start up this node without killing the main /rover_CONTROLLER node. Used by teleop_keyboard ''' self.rover_name = rover self.Obstacles = 0 self.MapLocation = Location(None) self.OdomLocation = Location(None) self.Targets = AprilTagDetectionArray() # Intialize this ROS node. if 'node_suffix' in kwargs and kwargs['node_suffix']: rospy.init_node(rover + '_CONTROLLER' + kwargs['node_suffix']) else: rospy.init_node(rover + '_CONTROLLER') # Create publishiers. self.sm_publisher = rospy.Publisher(rover + '/state_machine', String, queue_size=10, latch=True) self.status_publisher = rospy.Publisher(rover + '/status', String, queue_size=10, latch=True) self.info_publisher = rospy.Publisher('/infoLog', String, queue_size=10, latch=True) self.mode_publisher = rospy.Publisher(rover + '/mode', UInt8, queue_size=1, latch=True) self.finger_publisher = rospy.Publisher(rover + '/fingerAngle/cmd', Float32, queue_size=1, latch=True) self.wrist_publisher = rospy.Publisher(rover + '/wristAngle/cmd', Float32, queue_size=1, latch=True) # Wait for necessary services to be online. # Services are APIs calls to other neodes. rospy.wait_for_service(rover + '/control') rospy.wait_for_service(rover + '/map/find_nearest_target') rospy.wait_for_service(rover + '/map/get_obstacle_map') rospy.wait_for_service(rover + '/map/get_target_map') # Numpy-ify the GridMap GetMap._response_class = rospy.numpy_msg.numpy_msg(GridMap) # Connect to services. self.control = rospy.ServiceProxy(rover + '/control', Core) self._find_nearest_target = rospy.ServiceProxy(rover + '/map/find_nearest_target', FindTarget) self._get_obstacle_map = rospy.ServiceProxy(rover + '/map/get_obstacle_map', GetMap) self._get_target_map = rospy.ServiceProxy(rover + '/map/get_target_map', GetMap) self._start_magnetometer_calibration = rospy.ServiceProxy(rover + '/start_magnetometer_calibration', Empty) self._store_magnetometer_calibration = rospy.ServiceProxy(rover + '/store_magnetometer_calibration', Empty) # Subscribe to useful topics rospy.Subscriber(rover + '/odom/filtered', Odometry, self._odom) rospy.Subscriber(rover + '/odom/ekf', Odometry, self._map) rospy.Subscriber(rover + '/obstacle', Obstacle, self._obstacle) rospy.Subscriber(rover + '/targets', AprilTagDetectionArray, self._targets) # Transform listener. Use this to transform between coordinate spaces. self.xform = tf.TransformListener() # Wait for sensors and tf to have data (this sucks) rospy.sleep(1) print ('Welcome', self.rover_name, 'to the world of the future.') @sync(swarmie_lock) def _odom(self, msg) : self.OdomLocation.Odometry = msg @sync(swarmie_lock) def _map(self, msg) : self.MapLocation.Odometry = msg @sync(swarmie_lock) def _obstacle(self, msg) : self.Obstacles &= ~msg.mask self.Obstacles |= msg.msg @sync(swarmie_lock) def _targets(self, msg) : self.Targets = msg def __drive(self, request, **kwargs): request.obstacles = ~0 if 'ignore' in kwargs : request.obstacles = ~kwargs['ignore'] request.timeout = 120 if 'timeout' in kwargs : request.timeout = kwargs['timeout'] value = self.control([request]).result.result if 'throw' not in kwargs or kwargs['throw'] : if value == MoveResult.OBSTACLE_SONAR : raise ObstacleException(value) elif value == MoveResult.OBSTACLE_TAG : raise TagException(value) elif value == MoveResult.OBSTACLE_HOME : raise HomeException(value) elif value == MoveResult.PATH_FAIL : raise PathException(value) elif value == MoveResult.USER_ABORT : raise AbortException(value) elif value == MoveResult.TIMEOUT : raise TimeoutException(value) return value def stop(self): '''Stop the rover by placing it in manual mode.''' msg = UInt8() msg.data = 1 self.mode_publisher.publish(msg) def go(self): '''Start the rover by placing it into autonomous mode.''' msg = UInt8() msg.data = 2 self.mode_publisher.publish(msg) def circle(self, **kwargs): '''Drive in a small circle Args: * See keyword arguments for drive commands Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' if random.randint(0,1) == 0 : return self.timed_drive(15, 0.1, 0.62, **kwargs) else: return self.timed_drive(15, 0.1, -0.62, **kwargs) def timed_drive(self, time, linear, angular, **kwargs): '''Send the specified velocity command for a given period of time. Args: * time (float) The duration of the timed command. * linear (float) The linear velocity of the rover (m/s) * angular (float) The angular velocity of the rover (radians/s) SEE: Keyword Arguments for drive commands Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' req = MoveRequest( timer=time, linear=linear, angular=angular, ) return self.__drive(req, **kwargs) def drive(self, distance, **kwargs): '''Drive the specfied distance Args: * `distance` (`float`) Meters to drive. Keyword arguments: * `ignore` (`int`) - Bitmask with Obstacle messages that will be ignored while driving. * `throw` (`bool`) - Raise a DriveException if an obstacle is encountered (default True). * `timeout` (`int`) - The command will fail after this number of seconds (defulat: 120) Returns: * If `throw=False` was given returns a `mobility_msgs.msg.MoveResult` containing an integer. \ Values are described in `src/mobility/msg/MoveResult.msg` * If `throw=True` (the default) is given the return value will be converted into an exception. \ The following exceptions are defined: * `mobility.swarmie.DriveException` - Base class for driving exceptions. * `mobility.swarmie.VisionException` - Base class for exceptions caused by seeing a tag * `mobility.swarmie.TagException` - Exception caused when the target tag (0) is seen. * `mobility.swarmie.HomeException` - Exception caused when the home tag (256) is seen. * `mobility.swarmie.ObstacleException` - Exception caused when sonar senses the rover \ is close to an obstacle. * `mobility.swarmie.PathException` - Exception caused when the rover encounters an \ error while driving. If the rover detects a large angle between itself and its goal this \ happens. It's usually because the rover has driven over some kind of obstacle. * `mobility.swarmie.AbortException` - Exception caused when the user places the rover into \ manual mode while it was driving. * `mobility.swarmie.TimeoutException` - Exception caused when the drive command fails to \ complete in the amount of time specified with the `timeout=` argument. ''' req = MoveRequest( r=distance, ) return self.__drive(req, **kwargs) def turn(self, theta, **kwargs): '''Turn theta degrees Args: * `theta` (float) Radians to turn Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' req = MoveRequest( theta=theta, ) return self.__drive(req, **kwargs) def wait(self, time, **kwargs): '''Wait for a period of time. This can be used to check for obstacles Args: * `time` (`float`) seconds to wait. Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' req = MoveRequest( timer=time, ) return self.__drive(req, **kwargs) def set_wrist_angle(self, angle): '''Set the wrist angle to the specified angle Args: * `angle` (`float`) Wrist angle in radians. ''' self.wrist_publisher.publish(Float32(angle)) def set_finger_angle(self, angle): '''Set the finger angle to the spedified angle Args: * `angle` (`float`) Finger angle in radians. ''' self.finger_publisher.publish(Float32(angle)) def wrist_down(self): '''Lower the wrist to put it in the pickup position''' self.wrist_publisher.publish(Float32(1.25)) def wrist_up(self): '''Raise the wrist to the top''' self.wrist_publisher.publish(Float32(0.0)) def wrist_middle(self): '''Put the wrist in the middle of its travel so that the rover can drive with a block''' self.wrist_publisher.publish(Float32(0.75)) def fingers_open(self): '''Open the fingers''' self.finger_publisher.publish(Float32(math.pi/2)) def fingers_close(self): '''Close the fingers''' self.finger_publisher.publish(Float32(0.0)) def print_state_machine(self, msg): '''Print a message to the /rover/state_machine topic.''' s = String() s.data = msg self.sm_publisher.publish(s) def print_infoLog(self, msg): '''Print a message to the /infoLog topic this is viewable in the GUI''' s = String() s.data = msg self.info_publisher.publish(s) def print_status(self, msg): '''Print a message to the /rover/status topic this is viewable in the GUI''' s = String() s.data = msg self.status_publisher.publish(s) def has_block(self): '''Try to determine if a block is in our grasp. Uses the algorithm: * Raise the wrist all the way up. * Check if the center sonar is blocked at a close distance. If so, return `True` * Check if we can see a block that's very close. If so, return `True` * Check if this is the simulator. If so, return `True` * Return `False` ''' self.wrist_up() rospy.sleep(2) # First test: is something blocking the center sonar at a short range. obstacles = self.get_obstacle_condition() if obstacles & Obstacle.SONAR_BLOCK : return True # Second test: Can we see a bock that's close to the camera. blocks = self.get_latest_targets() blocks = sorted(blocks.detections, key=lambda x : abs(x.pose.pose.position.x)) if len(blocks) == 0 : return False nearest = blocks[0] x_dist = nearest.pose.pose.position.x if abs(x_dist) < 0.1 : return True # Third test: The block never seems to affect the sonar in the simulator. # Also, the grasped block rarely seems to be recognized in the simulator. # Which is whack. return(self.simulator_running()) def simulator_running(self): '''Helper Returns True if there is a /gazebo/link_states topic otherwise False''' for t in rospy.get_published_topics(): if t[0] == '/gazebo/link_states' : # This is the simulator return True return False def pickup(self): '''Picks up the block''' finger_close_angle = .5 if self.simulator_running(): finger_close_angle = 0 self.set_finger_angle(2) #open rospy.sleep(1) self.set_wrist_angle(1) rospy.sleep(.7) self.set_finger_angle(finger_close_angle) #close rospy.sleep(1) self.wrist_up() return(self.has_block()) def putdown(self): '''Puts the block down''' self.set_wrist_angle(1) rospy.sleep(.7) self.set_finger_angle(2) #open rospy.sleep(1) self.wrist_up() def find_nearest_target(self) : '''Broken: Return a XXX that is the odom location of the nearest target on the map.''' return self._find_nearest_target() def get_latest_targets(self) : '''Return the latest `apriltags_ros.msg.ArpilTagDetectionArray`. (it might be out of date)''' return self.Targets def get_obstacle_map(self): '''Return a `mapping.msg.RoverMap` that is the obstacle map. See `./src/mapping/src/mapping/__init__.py` for documentation of RoverMap''' return RoverMap(self._get_obstacle_map()) def get_target_map(self): '''Return a `mapping.msg.RoverMap` that is the targets map. See `./src/mapping/src/mapping/__init__.py` for documentation of RoverMap''' return RoverMap(self._get_target_map()) def start_magnetometer_calibration(self): '''Start calibrating the magnetometer on a rover.''' self._start_magnetometer_calibration() def store_magnetometer_calibration(self): '''Finish calibrating the magnetometer on a rover.''' self._store_magnetometer_calibration() def get_odom_location(self): '''Returns a `mobility.swarmie.Location` according to Odometery. This location will not jump arround and is locally accurate but will drift over time.''' with swarmie_lock : return self.OdomLocation def get_gps_location(self): '''Returns a `mobility.swarmie.Location` that is the output of the EKF that fuses GPS. This value has varying accuracy. The accuracy is reported in a covariance matrix. If you want to wait for a __good__ reading use `mobility.swarmie.Swarmie.wait_for_fix`''' with swarmie_lock : return self.MapLocation def wait_for_fix(self, distance=4, time=30): '''Wait until the GPS fix is reasonably accurate. This could take a while! Arguments: * `distance`: (`float`) The desired accuracty (+/- distance meters) with a likelyhood \ of 50%. Defaults to 4 meters. * `time`: (`int`) The number of seconds to wait for a good GPS measurement before giving up. \ Defaults to 30 seconds. Returns: * A `mobility.swarmie.Location` if the fix was successful. None if we waited until the timeout. ''' for i in xrange(time) : rospy.sleep(1) loc = self.get_gps_location() vx, vy, vz = loc.get_variances() if math.sqrt(vy) < distance : return loc return None def get_obstacle_condition(self): '''Returns the current obstacle condition. The presence of obstacles is indicated by bits in the returned integer. The definition of the bits can be found in `src/swarmie_msgs/msg/Obstacle.msg` Bit definitions: bit 1: SONAR_LEFT bit 2: SONAR_RIGHT bit 3: SONAR_CENTER bit 4: SONAR_BLOCK bit 8: TAG_TARGET bit 9: TAG_HOME Bit masks: IS_SONAR = SONAR_LEFT | SONAR_CENTER | SONAR_RIGHT | SONAR_BLOCK IS_VISION = TAG_TARGET | TAG_HOME ''' with swarmie_lock : return self.Obstacles def set_home_gps_location(self, loc): '''Remember the home GPS location reading. The location can be recalled by other control programs. Arguments: * loc: (`mobility.swarmie.Location`) The GPS coordinates to remember. ''' rospy.set_param('/' + self.rover_name + '/home_gps', {'x' : loc.Odometry.pose.pose.position.x, 'y' : loc.Odometry.pose.pose.position.y}) def get_home_gps_location(self): '''Recall the home GPS location. Returns: * (`geometry_msgs.msg.Point`) : The location of home. ''' return Point(**rospy.get_param('/' + self.rover_name + '/home_gps', {'x' : 0, 'y' : 0})) def has_home_gps_location(self): '''Check to see if the home location parameter is set. Returns: * (`bool`): True if the parameter exists, False otherwise. ''' return rospy.has_param('/' + self.rover_name + '/home_gps') def set_home_odom_location(self, loc): '''Remember the home odometry location. The location can be recalled by other control programs. Set this every time we see the nest to minimize the effect of drift. Arguments: * loc: (`mobility.swarmie.Location`) The coordinates to remember. ''' rospy.set_param('/' + self.rover_name + '/home_odom', {'x' : loc.Odometry.pose.pose.position.x, 'y' : loc.Odometry.pose.pose.position.y}) def get_home_odom_location(self): '''Recall the home odometry location. This is probably the most reliable memory of the location of the nest. Odometry drifts, so if we haven't seen home in a while this will be off. Returns: * (`geometry_msgs.msg.Point`) : The location of home. ''' return Point(**rospy.get_param('/' + self.rover_name + '/home_odom', {'x' : 0, 'y' : 0})) def has_home_odom_location(self): '''Check to see if the home odometry location parameter is set. Returns: * (`bool`): `True` if the parameter exists, `False` otherwise. ''' return rospy.has_param('/' + self.rover_name + '/home_odom') def drive_to(self, place, **kwargs): '''Drive directly to a particular point in space. The point must be in the odometry reference frame. Arguments: * `place`: (`geometry_msgs.msg.Point`): The place to drive. Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' loc = self.get_odom_location().get_pose() dist = math.hypot(loc.y - place.y, loc.x - place.x) angle = angles.shortest_angular_distance(loc.theta, math.atan2(place.y - loc.y, place.x - loc.x)) self.turn(angle, **kwargs) self.drive(dist, **kwargs) def set_heading(self, heading, **kwargs): '''Turn to face an absolute heading in radians. (zero is east) Arguments: * `heading`: (`float`) The heading in radians. Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' loc = self.get_odom_location().get_pose() angle = angles.shortest_angular_distance(loc.theta, heading) self.turn(angle, **kwargs)
Ancestors (in MRO)
Instance variables
var MapLocation
var Obstacles
var OdomLocation
var Targets
var control
var finger_publisher
var info_publisher
var mode_publisher
var rover_name
var sm_publisher
var status_publisher
var wrist_publisher
var xform
Methods
def __init__(
self, rover, **kwargs)
Constructor.
Args:
rover
(string
) - Name of the rover.
Keyword arguments:
node_suffix
(string
) - Optional argument to start up this node without killing the main /rover_CONTROLLER node. Used by teleop_keyboard
def __init__(self, rover, **kwargs): '''Constructor. Args: * `rover` (`string`) - Name of the rover. Keyword arguments: * `node_suffix` (`string`) - Optional argument to start up this node without killing the main /rover_CONTROLLER node. Used by teleop_keyboard ''' self.rover_name = rover self.Obstacles = 0 self.MapLocation = Location(None) self.OdomLocation = Location(None) self.Targets = AprilTagDetectionArray() # Intialize this ROS node. if 'node_suffix' in kwargs and kwargs['node_suffix']: rospy.init_node(rover + '_CONTROLLER' + kwargs['node_suffix']) else: rospy.init_node(rover + '_CONTROLLER') # Create publishiers. self.sm_publisher = rospy.Publisher(rover + '/state_machine', String, queue_size=10, latch=True) self.status_publisher = rospy.Publisher(rover + '/status', String, queue_size=10, latch=True) self.info_publisher = rospy.Publisher('/infoLog', String, queue_size=10, latch=True) self.mode_publisher = rospy.Publisher(rover + '/mode', UInt8, queue_size=1, latch=True) self.finger_publisher = rospy.Publisher(rover + '/fingerAngle/cmd', Float32, queue_size=1, latch=True) self.wrist_publisher = rospy.Publisher(rover + '/wristAngle/cmd', Float32, queue_size=1, latch=True) # Wait for necessary services to be online. # Services are APIs calls to other neodes. rospy.wait_for_service(rover + '/control') rospy.wait_for_service(rover + '/map/find_nearest_target') rospy.wait_for_service(rover + '/map/get_obstacle_map') rospy.wait_for_service(rover + '/map/get_target_map') # Numpy-ify the GridMap GetMap._response_class = rospy.numpy_msg.numpy_msg(GridMap) # Connect to services. self.control = rospy.ServiceProxy(rover + '/control', Core) self._find_nearest_target = rospy.ServiceProxy(rover + '/map/find_nearest_target', FindTarget) self._get_obstacle_map = rospy.ServiceProxy(rover + '/map/get_obstacle_map', GetMap) self._get_target_map = rospy.ServiceProxy(rover + '/map/get_target_map', GetMap) self._start_magnetometer_calibration = rospy.ServiceProxy(rover + '/start_magnetometer_calibration', Empty) self._store_magnetometer_calibration = rospy.ServiceProxy(rover + '/store_magnetometer_calibration', Empty) # Subscribe to useful topics rospy.Subscriber(rover + '/odom/filtered', Odometry, self._odom) rospy.Subscriber(rover + '/odom/ekf', Odometry, self._map) rospy.Subscriber(rover + '/obstacle', Obstacle, self._obstacle) rospy.Subscriber(rover + '/targets', AprilTagDetectionArray, self._targets) # Transform listener. Use this to transform between coordinate spaces. self.xform = tf.TransformListener() # Wait for sensors and tf to have data (this sucks) rospy.sleep(1) print ('Welcome', self.rover_name, 'to the world of the future.')
def circle(
self, **kwargs)
Drive in a small circle
Args:
- See keyword arguments for drive commands
Keyword Arguments/Returns/Raises:
- See
drive
def circle(self, **kwargs): '''Drive in a small circle Args: * See keyword arguments for drive commands Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' if random.randint(0,1) == 0 : return self.timed_drive(15, 0.1, 0.62, **kwargs) else: return self.timed_drive(15, 0.1, -0.62, **kwargs)
def drive(
self, distance, **kwargs)
Drive the specfied distance
Args:
distance
(float
) Meters to drive.
Keyword arguments:
ignore
(int
) - Bitmask with Obstacle messages that will be ignored while driving.throw
(bool
) - Raise a DriveException if an obstacle is encountered (default True).timeout
(int
) - The command will fail after this number of seconds (defulat: 120)
Returns:
-
If
throw=False
was given returns amobility_msgs.msg.MoveResult
containing an integer. Values are described insrc/mobility/msg/MoveResult.msg
-
If
throw=True
(the default) is given the return value will be converted into an exception. The following exceptions are defined:-
DriveException
- Base class for driving exceptions. -
VisionException
- Base class for exceptions caused by seeing a tag -
TagException
- Exception caused when the target tag (0) is seen. -
HomeException
- Exception caused when the home tag (256) is seen. -
ObstacleException
- Exception caused when sonar senses the rover is close to an obstacle. -
PathException
- Exception caused when the rover encounters an error while driving. If the rover detects a large angle between itself and its goal this happens. It's usually because the rover has driven over some kind of obstacle. -
AbortException
- Exception caused when the user places the rover into manual mode while it was driving. -
TimeoutException
- Exception caused when the drive command fails to complete in the amount of time specified with thetimeout=
argument.
-
def drive(self, distance, **kwargs): '''Drive the specfied distance Args: * `distance` (`float`) Meters to drive. Keyword arguments: * `ignore` (`int`) - Bitmask with Obstacle messages that will be ignored while driving. * `throw` (`bool`) - Raise a DriveException if an obstacle is encountered (default True). * `timeout` (`int`) - The command will fail after this number of seconds (defulat: 120) Returns: * If `throw=False` was given returns a `mobility_msgs.msg.MoveResult` containing an integer. \ Values are described in `src/mobility/msg/MoveResult.msg` * If `throw=True` (the default) is given the return value will be converted into an exception. \ The following exceptions are defined: * `mobility.swarmie.DriveException` - Base class for driving exceptions. * `mobility.swarmie.VisionException` - Base class for exceptions caused by seeing a tag * `mobility.swarmie.TagException` - Exception caused when the target tag (0) is seen. * `mobility.swarmie.HomeException` - Exception caused when the home tag (256) is seen. * `mobility.swarmie.ObstacleException` - Exception caused when sonar senses the rover \ is close to an obstacle. * `mobility.swarmie.PathException` - Exception caused when the rover encounters an \ error while driving. If the rover detects a large angle between itself and its goal this \ happens. It's usually because the rover has driven over some kind of obstacle. * `mobility.swarmie.AbortException` - Exception caused when the user places the rover into \ manual mode while it was driving. * `mobility.swarmie.TimeoutException` - Exception caused when the drive command fails to \ complete in the amount of time specified with the `timeout=` argument. ''' req = MoveRequest( r=distance, ) return self.__drive(req, **kwargs)
def drive_to(
self, place, **kwargs)
Drive directly to a particular point in space. The point must be in the odometry reference frame.
Arguments:
place
: (geometry_msgs.msg.Point
): The place to drive.
Keyword Arguments/Returns/Raises:
- See
drive
def drive_to(self, place, **kwargs): '''Drive directly to a particular point in space. The point must be in the odometry reference frame. Arguments: * `place`: (`geometry_msgs.msg.Point`): The place to drive. Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' loc = self.get_odom_location().get_pose() dist = math.hypot(loc.y - place.y, loc.x - place.x) angle = angles.shortest_angular_distance(loc.theta, math.atan2(place.y - loc.y, place.x - loc.x)) self.turn(angle, **kwargs) self.drive(dist, **kwargs)
def find_nearest_target(
self)
Broken: Return a XXX that is the odom location of the nearest target on the map.
def find_nearest_target(self) : '''Broken: Return a XXX that is the odom location of the nearest target on the map.''' return self._find_nearest_target()
def fingers_close(
self)
Close the fingers
def fingers_close(self): '''Close the fingers''' self.finger_publisher.publish(Float32(0.0))
def fingers_open(
self)
Open the fingers
def fingers_open(self): '''Open the fingers''' self.finger_publisher.publish(Float32(math.pi/2))
def get_gps_location(
self)
Returns a Location
that is the output of the EKF that fuses GPS.
This value has varying accuracy. The accuracy is reported in a covariance matrix.
If you want to wait for a good reading use wait_for_fix
def get_gps_location(self): '''Returns a `mobility.swarmie.Location` that is the output of the EKF that fuses GPS. This value has varying accuracy. The accuracy is reported in a covariance matrix. If you want to wait for a __good__ reading use `mobility.swarmie.Swarmie.wait_for_fix`''' with swarmie_lock : return self.MapLocation
def get_home_gps_location(
self)
Recall the home GPS location.
Returns:
- (
geometry_msgs.msg.Point
) : The location of home.
def get_home_gps_location(self): '''Recall the home GPS location. Returns: * (`geometry_msgs.msg.Point`) : The location of home. ''' return Point(**rospy.get_param('/' + self.rover_name + '/home_gps', {'x' : 0, 'y' : 0}))
def get_home_odom_location(
self)
Recall the home odometry location. This is probably the most reliable memory of the location of the nest. Odometry drifts, so if we haven't seen home in a while this will be off.
Returns:
- (
geometry_msgs.msg.Point
) : The location of home.
def get_home_odom_location(self): '''Recall the home odometry location. This is probably the most reliable memory of the location of the nest. Odometry drifts, so if we haven't seen home in a while this will be off. Returns: * (`geometry_msgs.msg.Point`) : The location of home. ''' return Point(**rospy.get_param('/' + self.rover_name + '/home_odom', {'x' : 0, 'y' : 0}))
def get_latest_targets(
self)
Return the latest apriltags_ros.msg.ArpilTagDetectionArray
. (it might be out of date)
def get_latest_targets(self) : '''Return the latest `apriltags_ros.msg.ArpilTagDetectionArray`. (it might be out of date)''' return self.Targets
def get_obstacle_condition(
self)
Returns the current obstacle condition. The presence of obstacles is indicated by bits in the returned integer.
The definition of the bits can be found in src/swarmie_msgs/msg/Obstacle.msg
Bit definitions:
bit 1: SONAR_LEFT bit 2: SONAR_RIGHT bit 3: SONAR_CENTER bit 4: SONAR_BLOCK bit 8: TAG_TARGET bit 9: TAG_HOME
Bit masks:
IS_SONAR = SONAR_LEFT | SONAR_CENTER | SONAR_RIGHT | SONAR_BLOCK IS_VISION = TAG_TARGET | TAG_HOME
def get_obstacle_condition(self): '''Returns the current obstacle condition. The presence of obstacles is indicated by bits in the returned integer. The definition of the bits can be found in `src/swarmie_msgs/msg/Obstacle.msg` Bit definitions: bit 1: SONAR_LEFT bit 2: SONAR_RIGHT bit 3: SONAR_CENTER bit 4: SONAR_BLOCK bit 8: TAG_TARGET bit 9: TAG_HOME Bit masks: IS_SONAR = SONAR_LEFT | SONAR_CENTER | SONAR_RIGHT | SONAR_BLOCK IS_VISION = TAG_TARGET | TAG_HOME ''' with swarmie_lock : return self.Obstacles
def get_obstacle_map(
self)
Return a mapping.msg.RoverMap
that is the obstacle map.
See ./src/mapping/src/mapping/__init__.py
for documentation of RoverMap
def get_obstacle_map(self): '''Return a `mapping.msg.RoverMap` that is the obstacle map. See `./src/mapping/src/mapping/__init__.py` for documentation of RoverMap''' return RoverMap(self._get_obstacle_map())
def get_odom_location(
self)
Returns a Location
according to Odometery. This location will not
jump arround and is locally accurate but will drift over time.
def get_odom_location(self): '''Returns a `mobility.swarmie.Location` according to Odometery. This location will not jump arround and is locally accurate but will drift over time.''' with swarmie_lock : return self.OdomLocation
def get_target_map(
self)
Return a mapping.msg.RoverMap
that is the targets map.
See ./src/mapping/src/mapping/__init__.py
for documentation of RoverMap
def get_target_map(self): '''Return a `mapping.msg.RoverMap` that is the targets map. See `./src/mapping/src/mapping/__init__.py` for documentation of RoverMap''' return RoverMap(self._get_target_map())
def go(
self)
Start the rover by placing it into autonomous mode.
def go(self): '''Start the rover by placing it into autonomous mode.''' msg = UInt8() msg.data = 2 self.mode_publisher.publish(msg)
def has_block(
self)
Try to determine if a block is in our grasp.
Uses the algorithm:
- Raise the wrist all the way up.
- Check if the center sonar is blocked at a close distance. If so, return
True
- Check if we can see a block that's very close. If so, return
True
- Check if this is the simulator. If so, return
True
- Return
False
def has_block(self): '''Try to determine if a block is in our grasp. Uses the algorithm: * Raise the wrist all the way up. * Check if the center sonar is blocked at a close distance. If so, return `True` * Check if we can see a block that's very close. If so, return `True` * Check if this is the simulator. If so, return `True` * Return `False` ''' self.wrist_up() rospy.sleep(2) # First test: is something blocking the center sonar at a short range. obstacles = self.get_obstacle_condition() if obstacles & Obstacle.SONAR_BLOCK : return True # Second test: Can we see a bock that's close to the camera. blocks = self.get_latest_targets() blocks = sorted(blocks.detections, key=lambda x : abs(x.pose.pose.position.x)) if len(blocks) == 0 : return False nearest = blocks[0] x_dist = nearest.pose.pose.position.x if abs(x_dist) < 0.1 : return True # Third test: The block never seems to affect the sonar in the simulator. # Also, the grasped block rarely seems to be recognized in the simulator. # Which is whack. return(self.simulator_running())
def has_home_gps_location(
self)
Check to see if the home location parameter is set.
Returns:
- (
bool
): True if the parameter exists, False otherwise.
def has_home_gps_location(self): '''Check to see if the home location parameter is set. Returns: * (`bool`): True if the parameter exists, False otherwise. ''' return rospy.has_param('/' + self.rover_name + '/home_gps')
def has_home_odom_location(
self)
Check to see if the home odometry location parameter is set.
Returns:
- (
bool
):True
if the parameter exists,False
otherwise.
def has_home_odom_location(self): '''Check to see if the home odometry location parameter is set. Returns: * (`bool`): `True` if the parameter exists, `False` otherwise. ''' return rospy.has_param('/' + self.rover_name + '/home_odom')
def pickup(
self)
Picks up the block
def pickup(self): '''Picks up the block''' finger_close_angle = .5 if self.simulator_running(): finger_close_angle = 0 self.set_finger_angle(2) #open rospy.sleep(1) self.set_wrist_angle(1) rospy.sleep(.7) self.set_finger_angle(finger_close_angle) #close rospy.sleep(1) self.wrist_up() return(self.has_block())
def print_infoLog(
self, msg)
Print a message to the /infoLog topic this is viewable in the GUI
def print_infoLog(self, msg): '''Print a message to the /infoLog topic this is viewable in the GUI''' s = String() s.data = msg self.info_publisher.publish(s)
def print_state_machine(
self, msg)
Print a message to the /rover/state_machine topic.
def print_state_machine(self, msg): '''Print a message to the /rover/state_machine topic.''' s = String() s.data = msg self.sm_publisher.publish(s)
def print_status(
self, msg)
Print a message to the /rover/status topic this is viewable in the GUI
def print_status(self, msg): '''Print a message to the /rover/status topic this is viewable in the GUI''' s = String() s.data = msg self.status_publisher.publish(s)
def putdown(
self)
Puts the block down
def putdown(self): '''Puts the block down''' self.set_wrist_angle(1) rospy.sleep(.7) self.set_finger_angle(2) #open rospy.sleep(1) self.wrist_up()
def set_finger_angle(
self, angle)
Set the finger angle to the spedified angle
Args:
angle
(float
) Finger angle in radians.
def set_finger_angle(self, angle): '''Set the finger angle to the spedified angle Args: * `angle` (`float`) Finger angle in radians. ''' self.finger_publisher.publish(Float32(angle))
def set_heading(
self, heading, **kwargs)
Turn to face an absolute heading in radians. (zero is east)
Arguments:
heading
: (float
) The heading in radians.
Keyword Arguments/Returns/Raises:
- See
drive
def set_heading(self, heading, **kwargs): '''Turn to face an absolute heading in radians. (zero is east) Arguments: * `heading`: (`float`) The heading in radians. Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' loc = self.get_odom_location().get_pose() angle = angles.shortest_angular_distance(loc.theta, heading) self.turn(angle, **kwargs)
def set_home_gps_location(
self, loc)
Remember the home GPS location reading. The location can be recalled by other control programs.
Arguments:
- loc: (
Location
) The GPS coordinates to remember.
def set_home_gps_location(self, loc): '''Remember the home GPS location reading. The location can be recalled by other control programs. Arguments: * loc: (`mobility.swarmie.Location`) The GPS coordinates to remember. ''' rospy.set_param('/' + self.rover_name + '/home_gps', {'x' : loc.Odometry.pose.pose.position.x, 'y' : loc.Odometry.pose.pose.position.y})
def set_home_odom_location(
self, loc)
Remember the home odometry location. The location can be recalled by other control programs. Set this every time we see the nest to minimize the effect of drift.
Arguments:
- loc: (
Location
) The coordinates to remember.
def set_home_odom_location(self, loc): '''Remember the home odometry location. The location can be recalled by other control programs. Set this every time we see the nest to minimize the effect of drift. Arguments: * loc: (`mobility.swarmie.Location`) The coordinates to remember. ''' rospy.set_param('/' + self.rover_name + '/home_odom', {'x' : loc.Odometry.pose.pose.position.x, 'y' : loc.Odometry.pose.pose.position.y})
def set_wrist_angle(
self, angle)
Set the wrist angle to the specified angle
Args:
angle
(float
) Wrist angle in radians.
def set_wrist_angle(self, angle): '''Set the wrist angle to the specified angle Args: * `angle` (`float`) Wrist angle in radians. ''' self.wrist_publisher.publish(Float32(angle))
def simulator_running(
self)
Helper Returns True if there is a /gazebo/link_states topic otherwise False
def simulator_running(self): '''Helper Returns True if there is a /gazebo/link_states topic otherwise False''' for t in rospy.get_published_topics(): if t[0] == '/gazebo/link_states' : # This is the simulator return True return False
def start_magnetometer_calibration(
self)
Start calibrating the magnetometer on a rover.
def start_magnetometer_calibration(self): '''Start calibrating the magnetometer on a rover.''' self._start_magnetometer_calibration()
def stop(
self)
Stop the rover by placing it in manual mode.
def stop(self): '''Stop the rover by placing it in manual mode.''' msg = UInt8() msg.data = 1 self.mode_publisher.publish(msg)
def store_magnetometer_calibration(
self)
Finish calibrating the magnetometer on a rover.
def store_magnetometer_calibration(self): '''Finish calibrating the magnetometer on a rover.''' self._store_magnetometer_calibration()
def timed_drive(
self, time, linear, angular, **kwargs)
Send the specified velocity command for a given period of time.
Args:
- time (float) The duration of the timed command.
- linear (float) The linear velocity of the rover (m/s)
-
angular (float) The angular velocity of the rover (radians/s)
SEE: Keyword Arguments for drive commands
Keyword Arguments/Returns/Raises:
- See
drive
def timed_drive(self, time, linear, angular, **kwargs): '''Send the specified velocity command for a given period of time. Args: * time (float) The duration of the timed command. * linear (float) The linear velocity of the rover (m/s) * angular (float) The angular velocity of the rover (radians/s) SEE: Keyword Arguments for drive commands Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' req = MoveRequest( timer=time, linear=linear, angular=angular, ) return self.__drive(req, **kwargs)
def turn(
self, theta, **kwargs)
def turn(self, theta, **kwargs): '''Turn theta degrees Args: * `theta` (float) Radians to turn Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' req = MoveRequest( theta=theta, ) return self.__drive(req, **kwargs)
def wait(
self, time, **kwargs)
Wait for a period of time. This can be used to check for obstacles
Args:
time
(float
) seconds to wait.
Keyword Arguments/Returns/Raises:
- See
drive
def wait(self, time, **kwargs): '''Wait for a period of time. This can be used to check for obstacles Args: * `time` (`float`) seconds to wait. Keyword Arguments/Returns/Raises: * See `mobility.swarmie.Swarmie.drive` ''' req = MoveRequest( timer=time, ) return self.__drive(req, **kwargs)
def wait_for_fix(
self, distance=4, time=30)
Wait until the GPS fix is reasonably accurate. This could take a while!
Arguments:
-
distance
: (float
) The desired accuracty (+/- distance meters) with a likelyhood of 50%. Defaults to 4 meters. -
time
: (int
) The number of seconds to wait for a good GPS measurement before giving up. Defaults to 30 seconds.
Returns:
- A
Location
if the fix was successful. None if we waited until the timeout.
def wait_for_fix(self, distance=4, time=30): '''Wait until the GPS fix is reasonably accurate. This could take a while! Arguments: * `distance`: (`float`) The desired accuracty (+/- distance meters) with a likelyhood \ of 50%. Defaults to 4 meters. * `time`: (`int`) The number of seconds to wait for a good GPS measurement before giving up. \ Defaults to 30 seconds. Returns: * A `mobility.swarmie.Location` if the fix was successful. None if we waited until the timeout. ''' for i in xrange(time) : rospy.sleep(1) loc = self.get_gps_location() vx, vy, vz = loc.get_variances() if math.sqrt(vy) < distance : return loc return None
def wrist_down(
self)
Lower the wrist to put it in the pickup position
def wrist_down(self): '''Lower the wrist to put it in the pickup position''' self.wrist_publisher.publish(Float32(1.25))
def wrist_middle(
self)
Put the wrist in the middle of its travel so that the rover can drive with a block
def wrist_middle(self): '''Put the wrist in the middle of its travel so that the rover can drive with a block''' self.wrist_publisher.publish(Float32(0.75))
def wrist_up(
self)
Raise the wrist to the top
def wrist_up(self): '''Raise the wrist to the top''' self.wrist_publisher.publish(Float32(0.0))
class TagException
class TagException(VisionException): pass
Ancestors (in MRO)
- TagException
- VisionException
- DriveException
- exceptions.Exception
- exceptions.BaseException
- __builtin__.object
Class variables
Instance variables
Methods
def __init__(
self, st)
Inheritance:
VisionException
.__init__
def __init__(self, st): self.status = st
class TimeoutException
class TimeoutException(DriveException): pass
Ancestors (in MRO)
- TimeoutException
- DriveException
- exceptions.Exception
- exceptions.BaseException
- __builtin__.object
Class variables
Instance variables
Methods
def __init__(
self, st)
Inheritance:
DriveException
.__init__
def __init__(self, st): self.status = st
class VisionException
class VisionException(DriveException): pass
Ancestors (in MRO)
- VisionException
- DriveException
- exceptions.Exception
- exceptions.BaseException
- __builtin__.object
Class variables
Instance variables
Methods
def __init__(
self, st)
Inheritance:
DriveException
.__init__
def __init__(self, st): self.status = st


Surging Sheffield beats Burnley 3-0 in Premier League
SHEFFIELD, England (AP) - Sheffield United returned to the Premier League after 12 years away with a mission to simply survive, but now it’s thriving.
Two goals from John Lundstram lifted Sheffield to a 3-0 win over Burnley on Saturday.
Sheffield rose to sixth place in the table following its fourth straight Premier League game unbeaten, with French forward Lys Mousset again playing a crucial role.
Mousset was credited with assists on both of Lundstram’s goals, as well as John Fleck’s third goal.
Mousset twice turned passes on for Lundstram to finish at the far post, and played a fine through ball for Fleck for the third. Mousset had scored three goals in Sheffield’s previous five league games, including the winning goal against Arsenal on Oct. 21.
Lundstram could have made it a hat trick in the 70th minute, but shot wide from a good position.
It was Burnley’s third straight league defeat, leaving Sean Dyche’s team four points above the relegation zone.
More AP soccer: https://apnews.com/Soccer and https://twitter.com/AP_Sports
Sign up for Daily Newsletters
Copyright © 2019 The Washington Times, LLC.
Please read our comment policy before commenting.


As a frequent user Chuck Diaz wants to find financial information easily accessible with a broad range of customizable options.
Select a link to continue:
Start Page
Persona
Interaction Flow
Conceptual Model


Please Login
Username
Password
{{error}}
Login to the Blog World
Haven't got an account? Please Signup
Signup as a New User
Alternatively you can still view blogs as a guest
Visit as a Guest


Tickets Available Now!
For more information about attending the conference, please read our Attendee's Guide.
The Buying Guide has information about financial assistance and discounts for students & unemployed, as well as options for volunteering, and details on how to apply for a free ticket.


| Service Mesh |
Auto Proxy Injection |
TCP + WebSockets |
HTTP, HTTP/2 |
gRPC |
Multi-Cluster |
Multi-Tenant |
Prometheus Integration |
Tracing Integration |
Encryption |
SPIFFE |
SPIRE |
{% assign meshes_by_category = site.data.landscape.meshes | sort: "category"
| reverse %} {% for meshes in meshes_by_category %}
|
{{meshes.name}}
|
{% include service-mesh-functionality-column.html GREAT=GREAT GOOD=GOOD
BAD=BAD COL=meshes.autoinject %} {% include
service-mesh-functionality-column.html GREAT=GREAT GOOD=GOOD BAD=BAD
COL=meshes.tcp-web %} {% include service-mesh-functionality-column.html
GREAT=GREAT GOOD=GOOD BAD=BAD COL=meshes.h2 %} {% include
service-mesh-functionality-column.html GREAT=GREAT GOOD=GOOD BAD=BAD
COL=meshes.grpc %} {% include service-mesh-functionality-column.html
GREAT=GREAT GOOD=GOOD BAD=BAD COL=meshes.multi-cluster %} {% include
service-mesh-functionality-column.html GREAT=GREAT GOOD=GOOD BAD=BAD
COL=meshes.multi-tenant %} {% include
service-mesh-functionality-column.html GREAT=GREAT GOOD=GOOD BAD=BAD
COL=meshes.prometheus %} {% include service-mesh-functionality-column.html
GREAT=GREAT GOOD=GOOD BAD=BAD COL=meshes.tracing %} {% include
service-mesh-functionality-column.html GREAT=GREAT GOOD=GOOD BAD=BAD
COL=meshes.encryption %}{% include
service-mesh-functionality-column.html GREAT=GREAT GOOD=GOOD BAD=BAD
COL=meshes.spiffe %}{% include
service-mesh-functionality-column.html GREAT=GREAT GOOD=GOOD BAD=BAD
COL=meshes.spire %}
{% endfor %}


Type Function Library audio.* Return value Boolean Revision Current Public Release (2013.2076) Keywords audio, seek, position Sample code /CoronaSDK/SampleCode/Media/AudioPlayer See also audio.rewind()
Seeks to a time position on either an active channel or directly on the audio handle.
This function returns true
on success or false
if otherwise.
There are subtle behavior differences depending on whether you used audio.loadSound() or audio.loadStream() on what you are trying to seek.
Audio loaded with audio.loadSound() may only seek using the channel parameter. You may not seek using the audioHandle. This is because audio.loadSound() is optimized to share the audio data so you can play back multiple instances of the sound simultaneously (at different positions). Seeking (seeking) the underlying data complicates this optimization.
In contrast, audio loaded with audio.loadStream() cannot be shared (you would load multiple instances of the same file if you needed multiple, simultaneous playback). So seeking the data does not cause a conflict. So generally you are expected to seek using the audioHandle parameter for audio loaded with audio.loadStream(). But if you seek streamed data using the channel parameter, it will automatically seek as if you used the audioHandle parameter. So you are allowed to specify either parameter safely.
Also note that for files loaded with audio.loadStream() and are currently playing, you may not hear the audio immediate update until after the current buffer finishes playing. If you want seemingly instantaneous seeking, you should stop the playback first using audio.stop(), seek, then start playing.
audio.seek( time [, audioHandle ] [, options ] )
-- e.g.
audio.seek( time [, audioHandle ] [, { channel=c } ] )
Number. The time in milliseconds within the audio handle you want to seek to.
Object. The audioHandle of the data you want to seek. Should only be used for audio loaded with audio.loadStream(). Do not use the channel parameter in the same call.
Table. Table that supports a single key: channel
, which is the channel you want the seek operation to apply to. Best for audio loaded with audio.loadSound(). Do not use the audioHandle
parameter in the same call.
audio.seek(3000) -- seek all active channels to 3 seconds
audio.seek(4000, backgroundMusic) -- seek the audio handle to 4 seconds
audio.seek(5000, { channel=1 } ) -- seek channel 1 to 5 seconds


After fertilization of an egg cell by a sperm cell, a woman will become pregnant. During this 9 month journey, many changes will happen.
Month 1
Month 2
Month 3
Month 4
Month 5
Month 6
Month 7
Month 8
Month 9
After 9 months, the baby is born!


{% comment %}Translators: When viewing the list of applications ready to be sent for a particular partner, this is the title of the page, where {{ object }} will be the name of the partner. Don't translate {{ object }}.{% endcomment %} {% blocktranslate trimmed %}Application data for {{ object }}{% endblocktranslate %}
{% if object.send_instructions %} {{ object.send_instructions | safe }} {% else %} {% comment %}Translators: When viewing the list of applications ready to be sent for a particular partner, this is instructions for the coordinator to click the 'mark as sent' button after they have sent the information.{% endcomment %} {% trans "When you've processed the data below, click the 'mark as sent' button." %} {% endif %}
{% if object.authorization_method == object.EMAIL %}{% comment %}Translators: When viewing the list of applications ready to be sent for a particular partner, this is the title of the section containing contact information for the people applications should be sent to.{% endcomment %} {% blocktranslate trimmed count object.contacts.all|length as counter %} Contact {% plural %} Contacts {% endblocktranslate %}
{% for contact in object.contacts.all %}{{ contact.full_name }} ({{ contact.short_name}})
{% if contact.title %} {{ contact.title }}{% endif %} {{ contact.email }}
{% if not forloop.last %}
{% endif %} {% empty %} {% comment %}Translators: When viewing the list of applications ready to be sent for a particular partner, this message shows if there is no information about who the applications should be sent to. Translate Wikipedia Library in the same way as the global branch is named (click through from https://meta.wikimedia.org/wiki/The_Wikipedia_Library).{% endcomment %} {% trans "Whoops, we don't have any listed contacts. Please notify Wikipedia Library administrators." %} {% endfor %} {% endif %} {% comment %}Translators: When viewing the list of applications ready to be sent for a particular partner, this is the title of the section containing the information about those applications.{% endcomment %}
{% trans "Application data" %}
{% if app_outputs %} {% if object.authorization_method == object.EMAIL %} {% elif object.authorization_method == object.CODES %}{% comment %}Translators: This text guides coordinators in using the code sending interface for approved applications. {% endcomment %} {% blocktranslate trimmed %} Use the dropdown menus to denote which editor will receive each code. Access codes will be sent to users automatically. {% endblocktranslate %}
{% endif %} {% else %} {% comment %}Translators: When viewing the list of applications ready to be sent for a particular partner, this message shows when there are none to show the coordinator.{% endcomment %} {% trans "There are no approved, unsent applications." %} {% endif %}


A Flexible one page portfolio theme,
for a full on user experience.
We implement Awesome ideas into full-scale Projects.
Fine Features
Honestly, these guys are the best people around to work with, They are
super commited, delivering exceptional work always.
Stephanie Windmill
Our Team
Ram Ratan
Developer
I am passionate about averything web
related, and a WordPress core contributor. I
love cofee too. I've been in Photoshop all
day and night.
Anna Lee
Client Service
I am passionate about averything web
related, and a WordPress core contributor. I
love cofee too. I've been in Photoshop all
day and night.
John Picle
Designer
I am passionate about averything web
related, and a WordPress core contributor. I
love cofee too. I've been in Photoshop all
day and night.
A Static content section
A Handy shortcode for intro text allows you to style text like that. Which is cool.
Interface design is what is between the machine and the human.  Interface design is chat is
between the machine and the human.
Design is the creation of a plan or convention for the construction of an object or a system (as in architectural blueprints, engineering drawing,
business process, circuit diagrams and sewing patterns).
Get in Touch
Meth Design Studio
We always look forward to meet new awesome people and discuss
brilliant project ideas. Come visit us! We have a great place to sit.
Our contact details
21 jump street
address line here too
15528 CA
<EMAIL_ADDRESS>T:23.444.221
F:23.555.333


Sir Michael Wilshaw was speaking on the day that Ofsted published the latest official statistics on inspection outcomes for the nation’s state schools that show 78 per cent of schools are now judged good or outstanding – compared to less than 70 per cent a year ago.
The 9 percentage point increase represents the most rapid rate of improvement in Ofsted’s 21-year history. It means that over 600,000 more pupils started the new term last week in schools rated good or outstanding than a year ago.
Speaking to a Manchester audience of more than 100 headteachers from across the North West whose schools or leadership have been rated outstanding since last September, HM Chief Inspector Sir Michael Wilshaw said:
The unprecedented rate of national improvement that this new data shows is cause for celebration.
Thanks to the work of dedicated teachers and outstanding headteachers up and down the country, England’s school system is making some genuine and radical advances. It means that thousands more children are getting at least a good standard of education. I am delighted to be able to come here and deliver the good news.
Sir Michael said he believed changes to Ofsted’s school inspection framework that came into force 12 months ago was clearly having a galvanising effect on England’s schools system.
In September 2012, a new grade of ‘requires improvement’ replaced the previous ‘satisfactory’ grade, with schools in this new category given a prescribed four years to improve – or face the prospect of being judged inadequate. During this period, inspectors inspect and monitor the school’s performance on a more frequent basis.
Sir Michael said:
This morning’s figures illustrate the greater urgency of heads, leaders, governors and teachers to improve their schools to a good standard and not put up with second-best.
Headteachers are using the ‘requires improvement’ judgement as a way of bringing about rapid improvement in their schools, especially in the quality of teaching. And the national improvement we are seeing is all the better for taking place under the terms of a more rigorous school inspection framework.
I am determined to use the power and influence of inspection to improve our education system. The message from Ofsted is unequivocal – the acceptable standard of education in this country now starts at ‘good’.
In total, 7,226 section 5 inspections were conducted in the 2012/13 academic year to June 2013 and published by August 2013. Of these, 39 per cent improved (2,789) since their last inspection, 41 per cent remained the same (2,945) and 18 per cent declined (1,314). In the 2011/12 academic year, 32 per cent of schools inspected improved.
All English regions have seen an increase since September 2012 in the proportion of their schools judged good or outstanding for overall effectiveness at their most recent inspection. The increases varied between 6 and 11 percentage points. The lowest increase was in the east of England, this is now the region with the lowest percentage of schools judged as good or outstanding (72 per cent). In August 2012 the lowest percentage of schools judged as good or outstanding was the West Midlands. The West Midlands snhowed thne highest increase (11 per cent) alongside the north east.
Notes to editors
-
The official statistics release: provisional inspections and outcomes of maintained schools between 1 April 2013 and 30 June 2013 is available online.
-
Overall effectiveness judgement of maintained schools inspected between 1 September 2012 and June 2013: 10 per cent outstanding; 54 per cent good; 30 per cent requires improvement; six per cent inadequate.
-
Most recent overall effectiveness judgement for maintained schools as at June 2013: 20 per cent outstanding; 58 per cent good; 19 per cent requires improvement; 3 per cent inadequate.


"HARE "(Hebrews ‘arnebeth) was prohibited as food according to the Mosaic law (Leviticus 11:6; Deuteronomy 14:7), “because he cheweth the cud, but divideth not the hoof.” The habit of this animal is to grind its teeth and move its jaw as if it actually chewed the cud. But, like the cony(q.v.), it is not a ruminant with four stomachs, but a rodent like the squirrel, rat, etc. Moses speaks of it according to appearance. It is interdicted because, though apparently chewing the cud, it did not divide the hoof. There are two species in Syria, (1) the Lepus Syriacus or Syrian hare, which is like the English hare; and (2) the Lepus Sinaiticus, or hare of the desert. No rabbits are found in Syria.
"HARE "(Hebrews ‘arnebeth) was prohibited as food according to the Mosaic law (Leviticus 11:6; Deuteronomy 14:7), “because he cheweth the cud, but divideth not the hoof.” The habit of this animal is to grind its teeth and move its jaw as if it actually chewed the cud. But, like the cony(q.v.), it is not a ruminant with four stomachs, but a rodent like the squirrel, rat, etc. Moses speaks of it according to appearance. It is interdicted because, though apparently chewing the cud, it did not divide the hoof.
There are two species in Syria, (1) the Lepus Syriacus or Syrian hare, which is like the English hare; and (2) the Lepus Sinaiticus, or hare of the desert. No rabbits are found in Syria.


- warn(String) - Static method in class com.github.privacystreams.utils.Logging
-
- WIFI_AP_LIST - Static variable in class com.github.privacystreams.device.DeviceState.Masks
-
- WIFI_AP_LIST - Static variable in class com.github.privacystreams.device.DeviceState
-
The list of currently scanned Wifi APs.
- WifiAp - Class in com.github.privacystreams.device
-
A WifiAp item represents the information of a WIFI AP.
- wrapSubStreamFunction(Function<List<Item>, Tout>) - Static method in class com.github.privacystreams.commons.item.ItemOperators
-
Output the grouped items in the item with a function.
- wrapValueGenerator(Function<Void, Tout>) - Static method in class com.github.privacystreams.commons.item.ItemOperators
-
Wrap a valueGenerator that takes Void as input type to a function that takes Item as input type.
- write(Item, Function<?, ? extends Stream>) - Method in class com.github.privacystreams.core.Stream
-
Write an item to the stream,
or write a null to end the stream.
- writeTo(String, boolean, boolean) - Static method in class com.github.privacystreams.storage.StorageOperators
-
Write an object to a local file, the output file will be at `filePath`.
- writeTo(Function<Tin, String>, boolean, boolean) - Static method in class com.github.privacystreams.storage.StorageOperators
-
Write an object to a local file, the output file path will be generated with a function.
- writeToFile(String, File, boolean) - Static method in class com.github.privacystreams.utils.StorageUtils
-


Waking Ned Devine A film review by Marty Mapes Copyright 1998 Marty Mapes
**1/2 (out of 4)Except that it's set in a small Irish village, WAKING NED DEVINE could pass for GRUMPY OLD MEN 3. Instead of Walter Matthau and Jack Lemmon, it stars two aging Irish actors, Ian Bannen and David Kelly.
Bannen and Kelly play Jackie and Michael, two old friends who don't act their age. (The two take motorcycle rides to the icy Atlantic to go skinny-dipping.) When they learn someone from their village (of just 52 people) has won the lottery, they concoct some wacky schemes to befriend the winner.
They target the 18 known lotto players from the village and invite them all over for a nice chicken supper.
Jackie trudges up to Devine's house in a storm, carrying a chicken supper as a bribe... gift.  The shock of winning the lottery must have given old Ned a heart attack.
Jackie and Michael try to claim the ticket for themselves, with Michael taking Ned's identity. They manage to fool the lotto man on the first visit, but he informs them he'll have to ask around - make sure Ned's who he says he is. Now Jackie and Michael have to include the whole town in the scheme if they want to avoid prison. They won't get their millions, but it still leaves £130,000 for every person in the village - if they can pull it off.
The movie's got a (mostly) good heart and more brain than you might think. Jackie's wife Annie (Fionnula Flanagan) is the movie's loving moral conscience. She makes the two heroes ponder the fraud they are committing and the potential wishes of the deceased. If this were truly a sitcom, such questions could be laughed off with a joke or two. But the two heroes take the question to heart and consider how they can do some good with the money.
The movie even remembers to tell us where the money would have gone, had not Jackie and Michael intervened. After all, the money wouldn't have vanished into thin air. It would have gone... well, you'll have to see for yourself.
There is only one time that the movie is unapologetically blackhearted, and it stands out in contrast to the rest of the film. It's a scene that's supposed to make you cheer, but it is unnecessarily cruel, and it calls into question the film's otherwise goodhearted nature. Many audiences actually did cheer, so you may too. But I found myself wincing at the films sudden wicked glee.
The film is full of colorful minor characters. There's a pig farmer in love with the town's flirt. She loves him too but can't stand the smell. There's a rookie minister who talks to the town's youngest boy, who has tough and practical questions about God.
Unfortunately, none of the minor characters is developed enough to really let you get attached. They are quirky, and at times amusing, but they are on the whole flat and robotic. The fact that the "evil" villager is dealt with so mercilessly is enough to tell you that Jones didn't consider his minor characters to be fully human, but rather offbeat icons of a small town.
WAKING NED DEVINE is no great film. The direction is adequate, if a bit predictable. The film's timing seems to be just a bit off. The sitcom aspect to the comedy feels a bit too contrived, as do the moments of earnest friendship. The widescreen cinematography is good, but disappointingly mundane given such a photogenic setting (the film was shot on the rugged and rustic Isle of Man).
On the other hand, I don't think it was striving for greatness. It's only supposed to be a lightweight, fun comedy. And on that level, it succeeds pretty well. If you're interested in seeing GRUMPY OLD IRISHMEN, don't let me stop you. It's not a bad movie, and it certainly can be entertaining.
Just don't say I sent you. --- Read an interview with Kirk Jones, director of Waking Ned Devine at http://net.indra.com/~mmapes/krkjones.htm
Check out more current movie reviews at http://www.indra.com/~mmapes/
-- Marty Mapes<EMAIL_ADDRESS>Movie Habit http://net.indra.com/~mmapes
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


LatticeKrig: Multiresolution Kriging Based on Markov Random Fields
Methods for the interpolation of large spatial
datasets. This package follows a "fixed rank Kriging" approach using
a large number of basis functions and provides spatial estimates
that are comparable to standard families of covariance functions.
Using a large number of basis functions allows for estimates that
can come close to interpolating the observations (a spatial model
with a small nugget variance.) Moreover, the covariance model for
this method can approximate the Matern covariance family but also
allows for a multi-resolution model and supports efficient
computation of the profile likelihood for estimating covariance
parameters. This is accomplished through compactly supported basis
functions and a Markov random field model for the basis
coefficients. These features lead to sparse matrices for the
computations and this package makes of the R spam package for this.
An extension of this version over previous ones ( < 5.4 ) is the
support for different geometries besides a rectangular domain. The
Markov random field approach combined with a basis function
representation makes the implementation of different geometries
simple where only a few specific functions need to be added with
most of the computation and evaluation done by generic routines that
have been tuned to be efficient. One benefit of this package's
model/approach is the facility to do unconditional and conditional
simulation of the field for large numbers of arbitrary points. There
is also the flexibility for estimating non-stationary covariances
and also the case when the observations are a linear combination
(e.g. an integral) of the spatial process. Included are generic
methods for prediction, standard errors for prediction, plotting of
the estimated surface and conditional and unconditional simulation.
Downloads:
Reverse dependencies:
Linking:
Please use the canonical form
https://CRAN.R-project.org/package=LatticeKrig
to link to this page.


{% extends "layout.html" %} {% block title %}Home{% endblock %} {% block navlist %}
Work-life balance is inherently linked to stress and stress related illness, as well as a lack of human productivity. Therefore the ability to predict a person's propensity to overwork or have a lack of leisure or self-care time etc. is very important. The healthcare industry already uses patient categorization to offer better tailored health services and more personalized care. The addition of work-life balance metrics to this would be extremely useful for improving this categorization.
Poor work-life balance has been correlated to stress-related illness
Healthcare Industries
e.g. hospitals, care providers, ACOs, insurance providers
To categorize customers and patients into risk groups
Use those categories to provide tailored health care


Bézier curves are used in many applications. They were first used to plot curves by Pierre Bézier in 1962, using them to model automotive bodies. In design, these curves are often used to greate so-called vector graphics; images that can be scaled without loss in quality, as opposed by raster graphics where pixels become visible if the image is scaled up.
A second application can be found in your browser. Sure, many browsers are capable of creating and displaying SVG (Scalable Vector Graphics) images, but the curves are more basic and subtle than that. Almost every animation/transition utilizes a Bézier curve for timing. You may want your animation to start slow, then accelerate, then slow down. You bet there's a Bézier curve for that! Below are some examples of Bézier curve animations and their CSS code:
cubic-bezier(1, 1, 0, 0)
cubic-bezier(0.54, 0.01, 0.46, 0.99)
cubic-bezier(0.43, 1.63, 0.71, -0.59)
Here are the functions (Bézier curves) describing these three animations:
These are just a few of many possible Bézier animation curves. In the figure to the right, we see how it all works. On the x-axis, time, the value of x is defined as such: The leftmost side marks the start of the animation, and the rightmost the end, with x changing value smoothly during this time. The value of y (the value of the curve at a certain value of x) specifies how far the animation has run. In fact, the gray lines in the three animations above are y axes and the dots mark exactly how far the animations have run. In curve 1, we see that the value of y is always the same as x, and the dot moves at a constant rate, but in curve 2 it moves a little at the start, then speeds up and slows down as the value of y changes less and less per every new, higher, value x.
They might seem difficult to plot, but Bézier curves work on fairly simple principles. It's all about dividing lines and placing points. Try this interactive little thing to understand how it all works:


This field is required.
This field is required to be at least 20 characters.
This field cannot be longer than 255 characters.
{{vm.question.question}}
This field is required.
This field should be more than 0.
This field cannot be more than 4.
This field should be a number.


ZeeWebist
Home
About
My Work
Contact
Contact Me
Get in touch with me
Send
Contact me
ZeeWebist
Email me at:
<EMAIL_ADDRESS>Let's Start Your New Project


The idea to create a potential improvement over Rotten Tomatoes’ method of aggregating movie reviews has been kicking around in my head for a few years, but it wasn’t until I learned Natural Language Processing (NLP) techniques that I was really able to implement the idea. Rotten Tomatoes creates its aggregated movie review scores by assigning a binary sentiment label to each review for a film (“fresh” for positive and “rotten” for negative) and taking an average of the binary scores to come up with an aggregated score between 0% and 100%. For example, if a movie’s reviews were all mildly positive, Rotten Tomatoes would assign a sentiment of positive to every review, resulting in a score of 100%. In contrast, if a movie had very polarizing reviews, for example, 50 very positive and 50 very negative reviews, this methodology would result in a potentially misleading 50% aggregated score.
My idea is that rather than use a binary sentiment classification, a continuous score between 0 and 1.0 can be assigned to each movie review. The aggregate score would then be based on an average of these ratings.
Unfortunately, many publications do not append handy scores to their reviews in order to use them in aggregation. Human taggers can read each review and assign a score based on the content of the review; however, this is extremely inefficient when hundreds of movies are released each year and many publications write reviews of these movies. This is where NLP comes in: machine learning can be used automatically assign a review score based on the text content of the headline and review, and that is exactly what I did.
In order to test a number of methods, I used three different types of models: a simple linear regression model, a recurrent neural network (RNN) model and a 1-dimensional convolutional neural network (CNN) model. The linear regression model used term frequency-inverse document frequency (TF-IDF) to convert the review text into numerical features a model could use. The RNN and CNN models both used word embeddings (learned during model training) to convert the text into model features.
All models were trained on a subset of data from the [Stanford Network Analysis Project] (https://snap.stanford.edu/data/web-Movies.html), which consists of approximately 8 million Amazon user reviews of over 250,000 movies. Once the models were trained, I tested it on actual movie reviews from newspaper and websites for four movies and created individual review and aggregate review scores for the four movies.
The full code for this project can be found as a Jupyter notebook here. In addition, there is a paper describing the full experiment and the results here.


We are The Monkee's, a famous band who love to perform at venue's and concerts
Here is our music video for 'Daydream Believer'.


--- layout: landingpage ---
A result-driven business/IT professional with in depth experience in applying SDLC methodologies in software development. Applied GAAP and IFRS guidelines while configuring ERP systems to ensure optimal integration and efficient information availability. Expertise in applying project planning, design including vision, blue print, configuration, data migration, unit testing, integration testing, end user training. Efficient in analyzing business requirements, needs, objectives and mapping them to functional specifications needed for system design and implementation.


Robots for the house will fill your robotic needs in your everyday life. You can find personnal and domestic robots, domestic robot accessories and replacement parts for your robots.


MEN OF HONOR
Reviewed by Harvey Karten Fox 2000 Pictures Director: George Tillman Jr. Writer: Scott Marshall Smith Cast: Robert De Niro, Cuba Gooding Jr., Charlize Theron, Aunjanue Ellis, Hal Holbrook, Michael Rapaport, David Conrad, Powers Boothe, David Keith Screened at: Cineplex Odeon Alpine, Brooklyn
I missed the critics' screening of "Men of Honor" and caught up with the picture not in a sophisticated Manhattan neighborhood but in a Brooklyn community filled with people who are politically and social conservative. As their voting record over the past few decades indicates, they are strongly family-minded, traditional, and at the Sunday screening I attended mostly over 55 years of age. The seats were filled. Why did "Men of Honor" attract the largest audience of the multiplex theater rather than "Charlie's Angels" or "Little Nicky" or "The 6th Day"? Because the other three films are targeted to the young? That's partly the reason. But I'd suggest another purely on speculation.  They look forward to movies that might urge them--were they just a little less inhibited--to stand up at the end and recite the pledge of allegiance or even sing the national anthem. "The Contender" would be a similar sort were the hero not a pro- choice, atheist vegetarian who likes sex, because absent those traits, who could resist the rousing call of President Jackson Evans to a joint session of Congress to accept his nomination of Laine Hanson to the post of vice president?
"Men of Honor" shares the all-American thrills of "The Contender" while celebrating an African-American man whose political views are unknown but whose determination to contribute mightily to his country is liberty-bell clear. His life could have been the subject of a dull, talking-heads biopic but director George Tillman Jr. does a bracing job of bringing this true American hero to life with all the force that a stirring sound track (by Mark Isham) and lines-are-drawn acting could bring. If the music obtrusively punctuates what is apparent in the struggle of Carl Brashear (Cuba Gooding Jr.) to overcome racial prejudice in the post World War II Navy (as scripted by Scott Marshall Smith), Tillman means well. If the obligatory courtroom finale is as schematic and schmaltzy as the conclusion of Rod Lurie "The Contender," all the better to appeal to a crowd less influenced by modern critical standards to condemn the mawkish. "Men of Honor" may be square, but in recent years we've had all the hip we need in the movie theaters.
Filmed by Anthony B. Richmond with some tense, authentic underwater photography, "Men of Honor" focuses on the struggle between Carl Brashear, who became the Navy's first African-American diver, and a crew of people headed by Master Chief Diver Billy Sunday (Robert De Niro). Pushed by his sharecropper father to be all he can be, Brashear enters the all-white Naval diving program. Despite his seventh- grade education, he struggles through the initial written tests, fails one, and passes the second with a reasonable grade. The real test comes for Brashear when he must deal with the refusal of the entire crew save the stuttering Snowhill (Michael Rapaport) to bunk with him. (All but Snowhill walk out...so where did they get to bunk anyway?) While Sunday is determined to flunk the man, pushed to do so by his racist commanding officer Mr. Pappy (Hal Holbrook), as he puffs away on his corncob pipe--a gift from General MacArthur--he slowly grows to appreciate Brashear's enormous motivation. This impetus to become a diver and even rise to the top of his profession is made most dramatic by what Brashear does to himself in the hospital while recovering from an accident.
Since Carl Brashear was a real, live person who--as the audience knew beforehand actually fought and won the good fight depicted here-- we in the audience knew from the start that this was a man that Billy Sunday could not shut down. Despite this, Tillman's characterizations bring out the humor as well as the poignancy, making the journey to victory the cause for celebration.
Rated R. Running time: 128 minutes. (C) 2000 by Harvey Karten<EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


In the Stack Name field, type in a name for your Cloudformation Stack, e.g. "voicebase-parquet-delivery"
In the CompanyName field, enter a unique string to represent your company (e.g. "mycompanyinc". This will be used to name your resources.
In the ExternalID field, enter your External ID. This is provided to you by Voicebase and is in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Choose the region your Voicebase account is hosted in (US or EU). Then click Next.
The next screen of stack options is optional. Click Next.
Finally, on the review screen, scroll down to check the box I acknowledge that AWS CloudFormation might create IAM resources with custom names, then click Create Stack.
Once the Cloudformation stack has completed creation, click the Outputs tab and copy the IAMRoleArn (in the format arn:aws:iam:[account number]:role/vb-[CompanyName]-s3-parquet-delivery-role) and the S3Bucket (in the format vb-[CompanyName]-s3-parquet-delivery. You will need these values to enter into the Voicebase Portal.
You will find the S3 bucket created in your list of S3 buckets with the name vb-[CompanyName]-s3-parquet-delivery.
Step 2: VoiceBase Portal Setup
In your VoiceBase account go to Settings/My Account/Edit/Data Output
Check that the Products widget for Enterprise Accelerator (EA) is toggled to Enable. If not, notify your VoiceBase admin.
Fill fields as follows, then click Enable:
External ID: provided by VoiceBase, previously entered in AWS/Create Stack
S3 Role: IAMRoleArn from AWS Outputs tab, as above


Toggle navigation
NIM Playground
Playground
History
Code
Result
Status
Waiting for input...
History
History of your executed code.
History is stored in browsers localStorage.
Clear History


×
Upload CSV
Clear
☰
Welcome!
Group Number
No.of Commits
Last Commit
1
5
21.01.19 , 9:00PM
1
5
21.01.19 , 9:00PM
1
5
21.01.19 , 9:00PM
1
5
21.01.19 , 9:00PM
1
5
21.01.19 , 9:00PM