22 from mvsim_comms
import pymvsim_comms
23 from mvsim_msgs
import SrvSetControllerTwist_pb2
24 from mvsim_msgs
import ObservationLidar2D_pb2
25 from mvsim_msgs
import SrvGetPose_pb2, SrvGetPoseAnswer_pb2
27 OBS_AVOIDANCE_PERIOD = 0.2
29 VIRTUAL_TARGET_DIST = 2.0
30 NEW_TARGET_PERIOD_SECONDS = 10
31 RANDOM_TARGET_RANGE = 30
32 TARGET_ATTRACTIVE_FORCE = 10
34 parser = argparse.ArgumentParser(prog=
'simple-obstacle-avoidance')
35 parser.add_argument(
'--vehicle', dest=
'vehicleName', action=
'store', required=
True,
36 help=
'The name of the vehicle to control in MVSIM')
38 args = parser.parse_args()
40 client = pymvsim_comms.mvsim.Client()
43 global prevLidarMsgTimestamp
44 prevLidarMsgTimestamp = 0
46 global prevGlobalGoalTimestamp
48 prevGlobalGoal = [0, 0]
49 prevGlobalGoalTimestamp = 0
56 req = SrvSetControllerTwist_pb2.SrvSetControllerTwist()
57 req.objectId = robotName
58 req.twistSetPoint.vx = vx
59 req.twistSetPoint.vy = vy
60 req.twistSetPoint.vz = 0
61 req.twistSetPoint.wx = 0
62 req.twistSetPoint.wy = 0
63 req.twistSetPoint.wz = w
65 client.callService(
'set_controller_twist', req.SerializeToString())
69 req = SrvGetPose_pb2.SrvGetPose()
70 req.objectId = robotName
71 ret = client.callService(
'get_pose', req.SerializeToString())
72 ans = SrvGetPoseAnswer_pb2.SrvGetPoseAnswer()
73 ans.ParseFromString(ret)
78 ang = -obs.aperture*0.5
79 dA = obs.aperture / (len(obs.scanRanges)-1)
82 resultantForce = [0, 0]
87 for idx, r
in enumerate(obs.scanRanges):
95 mod =
min(1e3, 1.0 / (r*r))
98 fx = -math.cos(ang) * mod
99 fy = -math.sin(ang) * mod
100 resultantForce[0] += fx * obsWeight
101 resultantForce[1] += fy * obsWeight
107 resultantForce[0] += math.cos(ang) * TARGET_ATTRACTIVE_FORCE
108 resultantForce[1] += math.sin(ang) * TARGET_ATTRACTIVE_FORCE
112 if (resultantForce[0] != 0)
or (resultantForce[1] != 0):
113 desiredDirection = math.atan2(resultantForce[1], resultantForce[0])
117 target_x = VIRTUAL_TARGET_DIST*math.cos(desiredDirection)
118 target_y = VIRTUAL_TARGET_DIST*math.sin(desiredDirection)
128 R = math.sqrt((target_x*target_x + target_y *
129 target_y)/(2*abs(target_y)))
138 global prevLidarMsgTimestamp
139 global prevGlobalGoalTimestamp, prevGlobalGoal
141 assert(msgType ==
"mvsim_msgs.ObservationLidar2D")
142 p = ObservationLidar2D_pb2.ObservationLidar2D()
143 p.ParseFromString(bytes(msg))
146 if (p.unixTimestamp > prevLidarMsgTimestamp+OBS_AVOIDANCE_PERIOD):
147 prevLidarMsgTimestamp = p.unixTimestamp
151 if (p.unixTimestamp > prevGlobalGoalTimestamp+NEW_TARGET_PERIOD_SECONDS):
152 prevGlobalGoalTimestamp = p.unixTimestamp
153 prevGlobalGoal = [(-0.5+random.random())*RANDOM_TARGET_RANGE,
154 (-0.5+random.random())*RANDOM_TARGET_RANGE]
157 if __name__ ==
"__main__":
158 client.setName(
"obstacle-avoidance")
159 print(
"Connecting to server...")
161 print(
"Connected successfully.")
163 print(
"===========================")
164 print(
"Configuration ")
165 print(
"- Vehicle to control: " + args.vehicleName)
166 print(
"===========================")
169 client.subscribeTopic(
"/" + args.vehicleName +
170 "/laser1_scan", onLidar2DMessage)
OutIt print(OutIt out, const xml_node< Ch > &node, int flags=0)
def evalObstacleAvoidance
static int min(int n1, int n2)
def onLidar2DMessage(msgType, msg)
def getRobotPose(client, robotName)
def sendRobotTwistSetpoint(client, robotName, vx, vy, w)