Beispiel #1
0
    def cc_ctrl(self):
        rospy.loginfo_throttle(1, "Running CC control")

        if (self.state.vx > 0.0):
            # get lhpt
            lhdist = 7  # todo determine from velocity
            s_lh = self.state.s + lhdist
            d_lh = self.cc_dref

            Xlh, Ylh = ptsFrenetToCartesian(np.array([s_lh]), \
                                            np.array([d_lh]), \
                                            np.array(self.pathlocal.X), \
                                            np.array(self.pathlocal.Y), \
                                            np.array(self.pathlocal.psi_c), \
                                            np.array(self.pathlocal.s))

            rho_pp = self.pp_curvature(self.state.X, self.state.Y,
                                       self.state.psi, Xlh[0], Ylh[0])
            delta_out = rho_pp * (self.lf + self.lr)  # kinematic feed fwd
        else:
            Xlh = 0.0
            Ylh = 0.0
            delta_out = 0.0

        self.vx_error = self.cc_vxref - self.state.vx
        if (self.robot_name == "gotthard"):
            k = 500
        elif (self.robot_name == "rhino"):
            k = 1500
        else:
            k = 0
            print "ERROR: incorrect /robot_name"
        dc_out = k * self.vx_error
        return delta_out, dc_out, Xlh, Ylh
Beispiel #2
0
    def pathLocalToPolArr(self):
        pa = PolygonArray()
        pa.header.stamp = rospy.Time.now()
        pa.header.frame_id = "map"
        for i in range(self.N-1):

            spoly = np.array([self.pathlocal.s[i], self.pathlocal.s[i+1],self.pathlocal.s[i+1],self.pathlocal.s[i]])
            dpoly = np.array([self.pathlocal.dub[i], self.pathlocal.dub[i+1],self.pathlocal.dlb[i+1],self.pathlocal.dlb[i]])
            Xpoly, Ypoly = ptsFrenetToCartesian(spoly,dpoly,self.pathlocal.X,self.pathlocal.Y,self.pathlocal.psi_c,self.pathlocal.s)

            p = PolygonStamped()
            p.header.stamp = rospy.Time.now()
            p.header.frame_id = "map"
            p.polygon.points = [Point32(x=Xpoly[0], y=Ypoly[0], z=0.0),
                                Point32(x=Xpoly[1], y=Ypoly[1], z=0.0),
                                Point32(x=Xpoly[2], y=Ypoly[2], z=0.0),
                                Point32(x=Xpoly[3], y=Ypoly[3], z=0.0)]


            pa.polygons.append(p)
            #pa.Color.r = 1.0
            #p.color.g = 0.0
            #p.color.b = 0.0        
        
        # color for mu
        pa.likelihood = self.pathlocal.mu[0:-1]*(0.2/np.max(self.pathlocal.mu)) # discarding final value
               
        #pa.color.r = 1.0
        #pa.color.g = 0.0
        #pa.color.b = 0.0
        
        return pa
Beispiel #3
0
# compute psic
dX = np.diff(X_cl)
dY = np.diff(Y_cl)
psic = np.arctan2(dY, dX)
psic_final = np.arctan2(Y_cl[0] - Y_cl[-1],
                        X_cl[0] - X_cl[-1])  # assuming closed track
psic = np.append(psic, psic_final)

## get left and right boundaries
#dlb = (-lanewidth/2.0)*np.ones(s.size)
#dub = (3.0*lanewidth/2.0)*np.ones(s.size)

dlb = -lanewidth * np.ones(s.size)
dub = lanewidth * np.ones(s.size)

X_ll, Y_ll = ptsFrenetToCartesian(s, dub, X_cl, Y_cl, psic, s)
X_rl, Y_rl = ptsFrenetToCartesian(s, dlb, X_cl, Y_cl, psic, s)

# downsample to get cone positions
threshold_dist_cones = 4
cones_left_X = [X_ll[0]]
cones_left_Y = [Y_ll[0]]
for i in range(X_ll.size - 1):
    dist = np.sqrt((X_ll[i] - cones_left_X[-1])**2 +
                   (Y_ll[i] - cones_left_Y[-1])**2)
    if (dist > threshold_dist_cones):
        cones_left_X.append(X_ll[i])
        cones_left_Y.append(Y_ll[i])
cones_left_X = np.array(cones_left_X)
cones_left_Y = np.array(cones_left_Y)
    def __init__(self):

        # timing params
        self.dt_sim = 0.01  # timestep of the simulation
        self.t_activate = rospy.get_param('/t_activate')
        self.t_final = rospy.get_param('/t_final')

        # pop-up scenario params
        self.s_ego_at_popup = rospy.get_param('/s_ego_at_popup')
        self.s_obs_at_popup = rospy.get_param('/s_obs_at_popup')
        self.d_obs_at_popup = rospy.get_param('/d_obs_at_popup')

        # track params
        self.track_name = rospy.get_param('/track_name')
        self.s_begin_mu_segments = rospy.get_param('/s_begin_mu_segments')
        self.mu_segment_values = rospy.get_param('/mu_segment_values')
        self.N_mu_segments = len(self.s_begin_mu_segments)
        self.mu_segment_idx = 0

        # vehicle params
        self.vehicle_width = rospy.get_param('/car/kinematics/l_width')

        # algo params (from acado)
        N = 40
        dt_algo = 0.1

        # init node subs pubs
        rospy.init_node('experiment_manager', anonymous=True)
        #self.clockpub = rospy.Publisher('/clock', Clock, queue_size=10)
        self.pathglobalsub = rospy.Subscriber("pathglobal", Path,
                                              self.pathglobal_callback)
        self.statesub = rospy.Subscriber("state", State, self.state_callback)
        self.carinfosub = rospy.Subscriber("/fssim/car_info", CarInfo,
                                           self.fssim_carinfo_callback)
        self.trajstarsub = rospy.Subscriber("trajstar", Trajectory,
                                            self.trajstar_callback)
        self.obspub = rospy.Publisher('/obs', Obstacles, queue_size=1)
        self.obsvispub = rospy.Publisher('/obs_vis', Marker, queue_size=1)
        self.tireparampub = rospy.Publisher('/tire_params',
                                            TireParams,
                                            queue_size=1)
        self.ctrl_mode_pub = rospy.Publisher('/ctrl_mode', Int16, queue_size=1)
        self.statetextmarkerpub = rospy.Publisher('/state_text_marker',
                                                  Marker,
                                                  queue_size=1)

        # init logging vars
        self.explog_activated = False
        self.explog_iterationcounter = 0
        self.stored_pathglobal = False
        self.stored_trajstar = False
        self.stored_trajcl = False
        self.explog_saved = False

        # init misc internal variables
        self.pathglobal = Path()
        self.received_pathglobal = False
        self.state = State()
        self.received_state = False
        self.trajstar = Trajectory()
        self.received_trajstar = False
        self.fssim_carinfo = CarInfo()

        while (not self.received_pathglobal):
            print("waiting for pathglobal")
            time.sleep(self.dt_sim * 100)

        # init experiment variables
        self.scenario_id = rospy.get_param('/scenario_id')
        self.tireparams = TireParams()
        self.obs = Obstacles()
        self.obs.s = [self.s_obs_at_popup]
        self.obs.d = [self.d_obs_at_popup]
        self.obs.R = [0.5]
        wiggleroom = 0.5
        self.obs.Rmgn = [
            0.5 * self.obs.R[0] + 0.5 * self.vehicle_width + wiggleroom
        ]
        Xobs, Yobs = ptsFrenetToCartesian(np.array(self.obs.s), \
                                          np.array(self.obs.d), \
                                          np.array(self.pathglobal.X), \
                                          np.array(self.pathglobal.Y), \
                                          np.array(self.pathglobal.psi_c), \
                                          np.array(self.pathglobal.s))
        self.ctrl_mode = 0  # # 0: stop, 1: cruise_ctrl, 2: tamp

        # Main loop
        #print 'running experiment: '
        #print 'track: ', self.track_name
        self.exptime = 0
        while (not rospy.is_shutdown()) and self.exptime < self.t_final:

            if (self.exptime >= self.t_activate):

                rospy.loginfo_throttle(1, "Running experiment")
                # HANDLE TRACTION IN SIMULATION
                s_ego = self.state.s % self.s_lap
                for i in range(self.N_mu_segments - 1):
                    if (self.s_begin_mu_segments[i] <= s_ego <=
                            self.s_begin_mu_segments[i + 1]):
                        self.mu_segment_idx = i
                        break
                if (s_ego >= self.s_begin_mu_segments[-1]):
                    self.mu_segment_idx = self.N_mu_segments - 1
                mu = self.mu_segment_values[self.mu_segment_idx]

                #print "s_ego =              ", s_ego
                #print "state.s =            ", self.state.s
                #print "self.N_mu_segments = ", self.N_mu_segments
                #print "mu_segment_idx =     ", self.mu_segment_idx
                #print "mu in this section = ", self.mu_segment_values[self.mu_segment_idx]

                # set tire params of sim vehicle

                if (0.0 <= mu < 0.3):  # ice
                    B = 4.0
                    C = 2.0
                    D = mu
                    E = 1.0
                elif (0.3 <= mu < 0.5):  # snow
                    B = 5.0
                    C = 2.0
                    D = mu
                    E = 1.0
                elif (0.5 <= mu < 0.9):  # wet
                    B = 12.0
                    C = 2.3
                    D = mu
                    E = 1.0
                elif (0.9 <= mu < 1.5):  # dry
                    B = 10.0
                    C = 1.9
                    D = mu
                    E = 0.97
                elif (1.5 <= mu <
                      2.5):  # dry + racing tires (gotthard default)
                    B = 12.56
                    C = 1.38
                    D = mu
                    E = 1.0
                else:
                    rospy.loginfo_throttle(1, "Faulty mu value in exp manager")

                self.tireparams.tire_coefficient = 1.0
                #self.tireparams.B = 10
                #self.tireparams.C = 1.9
                #self.tireparams.D = -mu
                #self.tireparams.E = 1.0
                self.tireparams.B = B
                self.tireparams.C = C
                self.tireparams.D = -D
                self.tireparams.E = E
                self.tireparams.header.stamp = rospy.Time.now()
                self.tireparampub.publish(self.tireparams)

                # POPUP SCENARIO
                if (self.scenario_id == 1):
                    self.ctrl_mode = 1  # cruise control
                    m_obs = self.getobstaclemarker(Xobs, Yobs, self.obs.R[0])
                    m_obs.color.a = 0.3  # transparent before detect
                    if (self.state.s >= self.s_ego_at_popup):
                        self.obspub.publish(self.obs)
                        m_obs.color.a = 1.0  # non-transparent after detect
                        self.ctrl_mode = 2  # tamp
                    self.obsvispub.publish(m_obs)

                # REDUCED MU TURN
                elif (self.scenario_id == 2):
                    self.ctrl_mode = 1  # pp cruise control from standstill
                    if (self.state.vx > 5):  # todo
                        self.ctrl_mode = 2  # tamp cruise control when we get up to speed

                # RACING
                else:
                    self.ctrl_mode = 2  # tamp

                # SEND STOP IF EXIT TRACK
                dlb = np.interp(self.state.s, self.pathglobal.s,
                                self.pathglobal.dlb)
                dub = np.interp(self.state.s, self.pathglobal.s,
                                self.pathglobal.dub)
                if (self.state.d < dlb or self.state.d > dub):
                    self.ctrl_mode = 0  # stop
                self.ctrl_mode_pub.publish(self.ctrl_mode)

                # publish text marker (state info)
                state_text = "vx: " + "%.3f" % self.state.vx + "\n"  \
                             "mu: " + "%.3f" % mu
                self.statetextmarkerpub.publish(self.gettextmarker(state_text))

                # save data for plot
                filename = "/home/larsvens/ros/tamp__ws/src/saarti/common/logs/explog_latest.npy"  # todo get from param
                self.s_begin_log = 195  # 190 todo get from param
                if (self.state.s >= self.s_begin_log
                        and not self.explog_activated):
                    print "STARTED EXPLOG"
                    t_start_explog = copy.deepcopy(self.exptime)
                    self.explog_activated = True
                    # store planned traj
                    self.trajstar_dict = {
                        "X": np.array(self.trajstar.X),
                        "Y": np.array(self.trajstar.Y),
                        "psi": np.array(self.trajstar.psi),
                        "s": np.array(self.trajstar.s),
                        "d": np.array(self.trajstar.d),
                        "deltapsi": np.array(self.trajstar.deltapsi),
                        "psidot": np.array(self.trajstar.psidot),
                        "vx": np.array(self.trajstar.vx),
                        "vy": np.array(self.trajstar.vy),
                        "ax": np.array(self.trajstar.ax),
                        "ay": np.array(self.trajstar.ay),
                        "Fyf": np.array(self.trajstar.Fyf),
                        "Fxf": np.array(self.trajstar.Fxf),
                        "Fyr": np.array(self.trajstar.Fyr),
                        "Fxr": np.array(self.trajstar.Fxr),
                        "Fzf": np.array(self.trajstar.Fzf),
                        "Fzr": np.array(self.trajstar.Fzr),
                        "kappac": np.array(self.trajstar.kappac),
                        "Cr": np.array(self.trajstar.Cr),
                        "t": np.arange(0, (N + 1) * dt_algo, dt_algo),
                    }
                    self.stored_trajstar = True

                    # initialize vars for storing CL traj
                    self.X_cl = []
                    self.Y_cl = []
                    self.psi_cl = []
                    self.s_cl = []
                    self.d_cl = []
                    self.deltapsi_cl = []
                    self.psidot_cl = []
                    self.vx_cl = []
                    self.vy_cl = []
                    self.ax_cl = []
                    self.ay_cl = []
                    self.t_cl = []
                    self.Fyf_cl = []
                    self.Fyr_cl = []
                    self.Fx_cl = []

                if (self.state.s >= self.s_begin_log and self.explog_activated
                        and self.exptime >= t_start_explog +
                        self.explog_iterationcounter * dt_algo):
                    # build CL traj
                    self.X_cl.append(self.state.X)
                    self.Y_cl.append(self.state.Y)
                    self.psi_cl.append(self.state.psi)
                    self.s_cl.append(self.state.s)
                    self.d_cl.append(self.state.d)
                    self.deltapsi_cl.append(self.state.deltapsi)
                    self.psidot_cl.append(self.state.psidot)
                    self.vx_cl.append(self.state.vx)
                    self.vy_cl.append(self.state.vy)
                    self.ax_cl.append(self.state.ax)
                    self.ay_cl.append(self.state.ay)
                    self.t_cl.append(self.exptime)
                    self.Fyf_cl.append(self.fssim_carinfo.Fy_f_l +
                                       self.fssim_carinfo.Fy_f_r)
                    self.Fyr_cl.append(self.fssim_carinfo.Fy_r)
                    self.Fx_cl.append(self.fssim_carinfo.Fx)

                    # store CL traj as dict
                    if (self.explog_iterationcounter == N
                        ):  # store N+1 values, same as trajstar
                        self.trajcl_dict = {
                            "X": np.array(self.X_cl),
                            "Y": np.array(self.Y_cl),
                            "psi": np.array(self.psi_cl),
                            "s": np.array(self.s_cl),
                            "d": np.array(self.d_cl),
                            "deltapsi": np.array(self.deltapsi_cl),
                            "psidot": np.array(self.psidot_cl),
                            "vx": np.array(self.vx_cl),
                            "vy": np.array(self.vy_cl),
                            "ax": np.array(self.ax_cl),
                            "ay": np.array(self.ay_cl),
                            "t": np.array(self.t_cl),
                            "Fyf": np.array(self.Fyf_cl),
                            "Fyr": np.array(self.Fyr_cl),
                            "Fx": np.array(self.Fx_cl),
                        }
                        self.stored_trajcl = True

                    self.explog_iterationcounter += 1
                # save explog

                # debug
                #print "stored_pathglobal: ", self.stored_pathglobal
                #print "stored_trajstar: ", self.stored_trajstar
                #print "stored_trajcl: ", self.stored_trajcl
                if (self.stored_pathglobal and self.stored_trajstar
                        and self.stored_trajcl and not self.explog_saved):
                    explog = {
                        "pathglobal": self.pathglobal_dict,
                        "trajstar": self.trajstar_dict,
                        "trajcl": self.trajcl_dict,
                    }

                    np.save(filename, explog)
                    self.explog_saved = True
                    print "SAVED EXPLOG"

            else:  # not reached activation time
                rospy.loginfo_throttle(
                    1, "Experiment starting in %i seconds" %
                    (self.t_activate - self.exptime))

            # handle exptime
            self.exptime += self.dt_sim
            msg = Clock()
            t_rostime = rospy.Time(self.exptime)
            msg.clock = t_rostime
            #self.clockpub.publish(msg)

            time.sleep(self.dt_sim)

        print 'simulation finished'

        # send shutdown signal
        message = 'run finished, shutting down'
        print message
        rospy.signal_shutdown(message)
pathglobal = pathglobal_npy.item()

start = 500
stop = 1500

Xpath = pathglobal['X'][start:stop]
Ypath = pathglobal['Y'][start:stop]
psipath = pathglobal['psi_c'][start:stop]
spath = pathglobal['s'][start:stop]

# define pts in s and d
s_in = 270
d_in = -15

# transform frenet --> cart
X, Y = ptsFrenetToCartesian(s_in, d_in, Xpath, Ypath, psipath, spath)

# transform cart --> frenet
s, d = ptsCartesianToFrenet(X, Y, Xpath, Ypath, psipath, spath)

# check results
print
print 's in          ', s_in
print 's out         ', s
print 's error       ', s_in - s

print
print 'd in          ', d_in
print 'd out         ', d
print 'd error       ', d_in - d
Beispiel #6
0
    def liveplot(self):
        tm = time.time()
        # clear figure
        self.a0.cla()
        self.a1.cla()

        N = len(self.trajstar.s)

        # plot lane lines
        nplot = int(1.0 * len(self.pathlocal.s))

        Xc = np.array(self.pathlocal.X[0:nplot])
        Yc = np.array(self.pathlocal.Y[0:nplot])
        dllub = np.array(self.pathlocal.dub[0:nplot])
        drlub = np.array(self.pathlocal.dlb[0:nplot])
        psic = np.array(self.pathlocal.psi_c[0:nplot])
        llX = Xc - dllub * np.sin(psic)
        llY = Yc + dllub * np.cos(psic)
        rlX = Xc - drlub * np.sin(psic)
        rlY = Yc + drlub * np.cos(psic)

        self.a0.plot(llX, llY, 'k')
        self.a0.plot(rlX, rlY, 'k')

        # plot obstacles
        Nobs = len(self.obstacles.s)
        for i in range(Nobs):

            # transform to cartesian
            #spt = self.obstacles.s[i]
            #dpt = self.obstacles.d[i]

            Xobs,Yobs = ptsFrenetToCartesian(self.obstacles.s[i], \
                                             self.obstacles.d[i], \
                                             self.pathlocal.X, \
                                             self.pathlocal.Y, \
                                             self.pathlocal.psi_c, \
                                             self.pathlocal.s)

            #Xcpt = np.interp(spt,self.pathlocal.s,self.pathlocal.X)
            #Ycpt = np.interp(spt,self.pathlocal.s,self.pathlocal.Y)
            #psicpt = np.interp(spt,self.pathlocal.s,self.pathlocal.psi_c)
            #Xobs,Yobs = ptsFrenetToCartesian(Xcpt,Ycpt,psicpt,dpt)

            # define obstacle circle
            Robs = self.obstacles.R[i]
            Rmgnobs = self.obstacles.Rmgn[i]
            Xpts, Ypts = getCirclePts(Xobs, Yobs, Rmgnobs, 20)
            self.a0.plot(Xpts, Ypts, 'r')
            Xpts, Ypts = getCirclePts(Xobs, Yobs, Robs, 20)
            self.a0.plot(Xpts, Ypts, 'r')

        # plot trajhat
        self.a0.plot(self.trajhat.X, self.trajhat.Y, '.b')

        # plot state constraint
        for k in range(N):
            slb = self.trajhat.slb[k]
            sub = self.trajhat.sub[k]
            dlb = self.trajhat.dlb[k]
            dub = self.trajhat.dub[k]
            n_intp = 3
            args = (np.linspace(sub, sub,
                                n_intp), np.linspace(sub, slb, n_intp),
                    np.linspace(slb, slb,
                                n_intp), np.linspace(slb, sub, n_intp))
            spts = np.concatenate(args)
            args = (np.linspace(dub, dlb,
                                n_intp), np.linspace(dlb, dlb, n_intp),
                    np.linspace(dlb, dub,
                                n_intp), np.linspace(dub, dub, n_intp))
            dpts = np.concatenate(args)

            Xpts,Ypts = ptsFrenetToCartesian(spts, \
                                             dpts, \
                                             self.pathlocal.X, \
                                             self.pathlocal.Y, \
                                             self.pathlocal.psi_c, \
                                             self.pathlocal.s)

            #Xcpts = np.interp(spts,self.pathlocal.s,self.pathlocal.X)
            #Ycpts = np.interp(spts,self.pathlocal.s,self.pathlocal.Y)
            #psicpts = np.interp(spts,self.pathlocal.s,self.pathlocal.psi_c)
            #Xpts, Ypts = ptsFrenetToCartesian(Xcpts, Ycpts, psicpts,dpts)
            self.a0.plot(Xpts, Ypts, 'm')

        # plot trajstar
        self.a0.plot(self.trajstar.X, self.trajstar.Y, '*m')

        # plot ego vehicle pose
        length_front = self.sp.lf + 0.75
        length_rear = self.sp.lr + 0.75
        width = self.sp.w
        R = np.matrix([[np.cos(self.state.psi),   np.sin(self.state.psi)], \
                       [-np.sin(self.state.psi),  np.cos(self.state.psi)]])

        corners = np.matrix([[length_front,  width/2], \
                             [-length_rear,  width/2], \
                             [-length_rear, -width/2], \
                             [length_front, -width/2], \
                             [length_front,  width/2]])
        corners = corners * R
        corners[:, 0] = corners[:, 0] + self.state.X
        corners[:, 1] = corners[:, 1] + self.state.Y

        self.a0.plot(corners[:, 0], corners[:, 1], 'k')

        # plot real friction circle

        # plot algo friction circle
        Fxfpts, Fyfpts = getCirclePts(0, 0, self.dp.mu_alg * self.dp.Fzf, 100)
        self.a1.plot(Fxfpts, Fyfpts, 'k')

        # plot trajhat forces
        #print len(self.trajhat.Fxf)
        #print len(self.trajhat.Fyf)
        #self.a1.plot(self.trajhat.Fxf, self.trajhat.Fyf, 'xr')

        # plot trajstar forces [x / myInt for x in myList]
        self.a1.plot([x / 2.0 for x in self.trajstar.Fx], self.trajstar.Fyf,
                     'xb')

        self.a1.set_xlabel('Fxf')
        self.a1.set_ylabel('Fyf')

        # redraw plot
        plt.draw()
        plt.pause(0.001)

        # print plot time
        elapsed = time.time() - tm
Beispiel #7
0
f0_ax7.set_title("Fx")
f0_ax8 = f0.add_subplot(gs[2, 2])
f0_ax8.set_title("Fxr (u3)")
f0_ax9 = f0.add_subplot(gs[3, 2])
f0_ax9.set_title("Ff")
f0_ax10 = f0.add_subplot(gs[4, 2])
f0_ax10.set_title("Fr")

#
# OVERHEAD VIEW
#

# global path
Xll,Yll = ptsFrenetToCartesian(np.array(pathglobal['s']), \
                                 np.array(pathglobal['dub']), \
                                 np.array(pathglobal['X']), \
                                 np.array(pathglobal['Y']), \
                                 np.array(pathglobal['psi_c']), \
                                 np.array(pathglobal['s']))
Xrl,Yrl = ptsFrenetToCartesian(np.array(pathglobal['s']), \
                                 np.array(pathglobal['dlb']), \
                                 np.array(pathglobal['X']), \
                                 np.array(pathglobal['Y']), \
                                 np.array(pathglobal['psi_c']), \
                                 np.array(pathglobal['s']))

f0_ax0.plot(Xll, Yll, 'k')
f0_ax0.plot(Xrl, Yrl, 'k')

# planned traj
#f0_ax0.plot(trajstar["X"],trajstar["Y"],'b',linewidth=3.0)
line_trajstar = f0_ax0.add_collection(
Beispiel #8
0
    def __init__(self):
        rospy.init_node('track_interface', anonymous=True)
        self.pathglobalpub = rospy.Publisher('pathglobal', Path, queue_size=10)
        self.pathglobalvispub = rospy.Publisher('pathglobal_vis', navPath, queue_size=10)
        self.dubvispub = rospy.Publisher('dubglobal_vis', navPath, queue_size=10)
        self.dlbvispub = rospy.Publisher('dlbglobal_vis', navPath, queue_size=10)
        self.track_sub = rospy.Subscriber("/fssim/track", Track, self.track_callback)
        self.track = Track()
        self.pathglobal = Path()
        self.received_track = False
        self.rate = rospy.Rate(1)
        
        # set params
        ds = 1.0 # step size in s # 0.5 nominal
        plot_track = False
        plot_orientation = False
        plot_dlbdub = False
        plot_mu = False
        self.s_begin_mu_segments = rospy.get_param('/s_begin_mu_segments')
        self.mu_segment_values = rospy.get_param('/mu_segment_values')
        self.N_mu_segments = len(self.s_begin_mu_segments)
        
        # wait for track
        while(not self.received_track):
            print "waiting for track"
            self.rate.sleep()      

        # get cone positions left and right as numpy arrays
        cl_X = []
        cl_Y = []
        for i in range(len(self.track.cones_left)):
            cl_X.append(self.track.cones_left[i].x)
            cl_Y.append(self.track.cones_left[i].y)            
        cl_X = np.array(cl_X)
        cl_Y = np.array(cl_Y)
        print "nr of cones left: ", cl_X.size
        
        cr_X = []
        cr_Y = []
        for i in range(len(self.track.cones_right)):    
            cr_X.append(self.track.cones_right[i].x)
            cr_Y.append(self.track.cones_right[i].y) 
        cr_X = np.array(cr_X)
        cr_Y = np.array(cr_Y)
        print "nr of cones right: ", cr_X.size

        # compute rough centerline
        ccl_X = []
        ccl_Y = []
        for i in range(cl_X.size):
            pt_left = {"X": cl_X[i], "Y": cl_Y[i]}
            # find closest right cone
            dist = np.sqrt((cr_X-pt_left["X"])**2 + (cr_Y-pt_left["Y"])**2)
            idx = np.argmin(dist)
            pt_right = {"X": cr_X[idx], "Y": cr_Y[idx]}
            pt_mid = {"X": 0.5*(pt_left["X"]+pt_right["X"]), "Y": 0.5*(pt_left["Y"]+pt_right["Y"])}
            ccl_X.append(pt_mid["X"])
            ccl_Y.append(pt_mid["Y"])
        ccl_X = np.array(ccl_X)
        ccl_Y = np.array(ccl_Y)
        
        # get approximate length of track
        stot = 0
        for i in range(ccl_X.size-1):
            stot += np.sqrt((ccl_X[i+1]-ccl_X[i])**2 + (ccl_Y[i+1]-ccl_Y[i])**2)
        stot = (stot//ds)*ds
        print "length of track: stot = ", str(stot)
        
        # set s
        s = np.arange(0, stot, ds)
        
        # parametric spline interpolation
        print "spline interpolation of centerline"
        N = int(stot/ds)
        unew = np.arange(0, 1.0, 1.0/N) # N equidistant pts
        # center
        tck, u = interpolate.splprep([ccl_X, ccl_Y], s=0)
        out = interpolate.splev(unew, tck)
        fcl_X = out[0]
        fcl_Y = out[1]
        # left
        tck, u = interpolate.splprep([cl_X, cl_Y], s=0)
        out = interpolate.splev(unew, tck)
        fll_X = out[0]
        fll_Y = out[1]        
        # right
        tck, u = interpolate.splprep([cr_X, cr_Y], s=0)
        out = interpolate.splev(unew, tck)
        frl_X = out[0]
        frl_Y = out[1]

        # set psic
        print "computing psic"        
        dX = np.diff(fcl_X)
        dY = np.diff(fcl_Y)

        psic = np.arctan2(dY,dX)
        psic_final = np.arctan2(fcl_Y[0]-fcl_Y[-1],fcl_X[0]-fcl_X[-1])  
        psic = np.append(psic,psic_final) # assuming closed track

        # separate in pieces (for 2pi flips)
        idx_low = 0
        idx_high = 0
        psic_piecewise = []
        s_piecewise = []
        for i in range(psic.size-1):
            if(np.abs(psic[i+1] - psic[i]) > np.pi ): 
                # if single pt, remove
                if(np.abs(psic[i+2] - psic[i]) < np.pi ):
                    print("removing single flip")
                    psic[i+1] = psic[i]
                # otherwise make a piece
                else:
                    print("making pieces (psic flips)")
                    idx_high = i+1
                    psic_piece = psic[idx_low:idx_high]
                    psic_piecewise.append(psic_piece)
                    s_piece = s[idx_low:idx_high]
                    s_piecewise.append(s_piece)
                    idx_low = i+1
                                  
        # add final piece
        psic_piece = psic[idx_low:psic.size]
        psic_piecewise.append(psic_piece)
        s_piece = s[idx_low:psic.size]
        s_piecewise.append(s_piece)
        
        # shift pieces to make continous psi_c
        for j in range(len(psic_piecewise)-1):
            while(psic_piecewise[j][-1] - psic_piecewise[j+1][0] > np.pi):
                psic_piecewise[j+1] = psic_piecewise[j+1] + 2*np.pi
                
            while(psic_piecewise[j][-1] - psic_piecewise[j+1][0] <= -np.pi):
                psic_piecewise[j+1] = psic_piecewise[j+1] - 2*np.pi
        
        # concatenate pieces
        psic_cont = psic_piecewise[0]
        for j in range(len(psic_piecewise)-1):
            psic_cont = np.concatenate((psic_cont,psic_piecewise[j+1]))        
        
        # downsample for smoother curve
        step = 5 #11
        print "interpolating downsampled psic with step size ", str(step)
        s_ds = s[0::step]
        s_ds = np.append(s_ds,s[-1]) # append final value for closed circuit
        psic_ds = psic_cont[0::step]
        psic_ds = np.append(psic_ds,psic_cont[-1]) # append final value for closed circuit
        
        # interpolate 
        t, c, k = interpolate.splrep(s_ds, psic_ds, s=0, k=4)
        psic_spl = interpolate.BSpline(t, c, k, extrapolate=False)
        
        # compute derrivatives (compare with naive numerical) 
        print "computing derivatives of psic"
        kappac_spl = psic_spl.derivative(nu=1)
        kappacprime_spl = psic_spl.derivative(nu=2)
        
        # put psi_c back on interval [-pi,pi]
        psic_out = psic_spl(s)
        #plt.plot(psic_out)
        psic_out = angleToInterval(psic_out)

        # tmp test helpers
        #plt.plot(psic_out,'*')
        #psic_out = angleToContinous(psic_out)
        #plt.plot(psic_out,'.')
        #plt.show()

        # set kappac        
        kappac_out = kappac_spl(s)
        kappacprime_out = kappacprime_spl(s)

        # set dlb and dub
        print "setting dlb and dub"
        dub = []
        dlb = []
        for i in range(N):
            X = fcl_X[i]
            Y = fcl_Y[i]
            # left
            dub_ele =  np.amin(np.sqrt((fll_X-X)**2 + (fll_Y-Y)**2))
            # right
            dlb_ele = -np.amin(np.sqrt((frl_X-X)**2 + (frl_Y-Y)**2))
            
            # correction if dlb or dub w.r.t zero division in dynamics  
            th = 0.3            
            while(abs(1.0-dub_ele*kappac_out[i]) < th):
                dub_ele=dub_ele-0.01
                print "adjusting dub"
            while(abs(1.0-dlb_ele*kappac_out[i]) < th):
                dlb_ele=dlb_ele+0.01
                print "adjusting dub"
                
            dub.append(dub_ele)
            dlb.append(dlb_ele)
                
        dub = np.array(dub)
        dlb = np.array(dlb)      
        
        # set mu 
        mu = []
        for i in range(N): 
            mu_ele = self.mu_segment_values[-1]
            for j in range(self.N_mu_segments-1):
                if(self.s_begin_mu_segments[j]-0.01 <= s[i] <= self.s_begin_mu_segments[j+1]):
                    mu_ele = self.mu_segment_values[j]
                    break                    
            mu.append(mu_ele)
        mu = np.array(mu)
        
        # plot to see what we're doing  
        if plot_orientation:   
            fig, axs = plt.subplots(3,1)
            axs[0].plot(s,psic,'k*')
            axs[0].set_title('psic')
            #for j in range(len(psic_piecewise)):
            #    ax.plot(s_piecewise[j],psic_piecewise[j],'.')
            #ax.plot(s,psic_cont,'r')        
            axs[0].plot(s,psic_out,'m.')
            
            axs[1].plot(s,kappac_out,'.m')
            axs[1].set_title('kappac')
            
            
            plt.show()
        
        if plot_track:
            fig, ax = plt.subplots()
            ax.axis("equal")
            ax.plot(fcl_X,fcl_Y, '.b') # fine centerline
            ax.plot(fll_X,fll_Y, '.b') # fine left line
            ax.plot(frl_X,frl_Y, '.b') # fine right line
            ax.plot(cl_X,cl_Y, '*k') # cones left
            ax.plot(cr_X,cr_Y, '*k') # cones right 
            ax.plot(ccl_X,ccl_Y, '*r') # coarse centerline
            plt.show()
            
        if plot_dlbdub:
            fig, axs = plt.subplots(3,1)
            axs[0].plot(s,dlb,'.b')
            axs[1].plot(s,dub,'.b')
            axs[2].plot(s,1.0/kappac_out,'r.')
            #axs[2]([np.min(dlb),np.max(dub)])
            plt.show()
        
        if plot_mu:
            fig, ax = plt.subplots()
            ax.plot(s,mu,'.b')
            plt.show()        

        # put all in message and publish
        self.pathglobal.X = fcl_X
        self.pathglobal.Y = fcl_Y
        self.pathglobal.s = s
        self.pathglobal.psi_c = psic_out
        self.pathglobal.kappa_c = kappac_out
        self.pathglobal.kappaprime_c = kappacprime_out
        self.pathglobal.theta_c = np.zeros(N) # grade/bank implement later
        self.pathglobal.mu = mu
        self.pathglobal.dub = dub
        self.pathglobal.dlb = dlb
        
        print "publishing pathglobal"
        self.pathglobalpub.publish(self.pathglobal)

        # publish paths for rviz
        pathglobalvis = navPath()
        for i in range(N):
            pose = PoseStamped()
            pose.header.stamp = rospy.Time.now()
            pose.header.frame_id = "map"
            pose.pose.position.x = fcl_X[i]
            pose.pose.position.y = fcl_Y[i]            
            quaternion = tf.transformations.quaternion_from_euler(0, 0, psic[i])
            pose.pose.orientation.x = quaternion[0]
            pose.pose.orientation.y = quaternion[1]
            pose.pose.orientation.z = quaternion[2]
            pose.pose.orientation.w = quaternion[3]
            pathglobalvis.poses.append(pose)
        pathglobalvis.header.stamp = rospy.Time.now()
        pathglobalvis.header.frame_id = "map"
        print "publishing pathglobal visualization"
        self.pathglobalvispub.publish(pathglobalvis)

        # test correctness of dub and dlb in rviz
        Xleft,Yleft = ptsFrenetToCartesian(s,dub,fcl_X,fcl_Y,psic,s)
        pathleft = navPath()
        pathleft.header.stamp = rospy.Time.now()
        pathleft.header.frame_id = "map"
        for i in range(N):
            pose = PoseStamped()
            pose.header.stamp = rospy.Time.now()
            pose.header.frame_id = "map"
            pose.pose.position.x = Xleft[i]
            pose.pose.position.y = Yleft[i]            
            pathleft.poses.append(pose)
        self.dubvispub.publish(pathleft)
        
        Xright,Yright = ptsFrenetToCartesian(s,dlb,fcl_X,fcl_Y,psic,s)
        pathright = navPath()        
        pathright.header.stamp = rospy.Time.now()
        pathright.header.frame_id = "map"
        for i in range(N):
            pose = PoseStamped()
            pose.header.stamp = rospy.Time.now()
            pose.header.frame_id = "map"
            pose.pose.position.x = Xright[i]
            pose.pose.position.y = Yright[i]            
            pathright.poses.append(pose)
        self.dlbvispub.publish(pathright)