#!/usr/bin/env python
import sympy as sp
import numpy as np
def cross ( x ) :
ret = sp . Matrix ( np . zeros ( ( 3 , 3 ) ) )
ret [ 0 , 1 ] , ret [ 0 , 2 ] = - x [ 2 ] , x [ 1 ]
ret [ 1 , 0 ] , ret [ 1 , 2 ] = x [ 2 ] , - x [ 0 ]
ret [ 2 , 0 ] , ret [ 2 , 1 ] = - x [ 1 ] , x [ 0 ]
return ret
def euler_rotate ( roll , pitch , yaw ) :
# make symbolic rotation matrix from eulers
matrix_roll = sp . Matrix ( [ [ 1 , 0 , 0 ] ,
[ 0 , sp . cos ( roll ) , - sp . sin ( roll ) ] ,
[ 0 , sp . sin ( roll ) , sp . cos ( roll ) ] ] )
matrix_pitch = sp . Matrix ( [ [ sp . cos ( pitch ) , 0 , sp . sin ( pitch ) ] ,
[ 0 , 1 , 0 ] ,
[ - sp . sin ( pitch ) , 0 , sp . cos ( pitch ) ] ] )
matrix_yaw = sp . Matrix ( [ [ sp . cos ( yaw ) , - sp . sin ( yaw ) , 0 ] ,
[ sp . sin ( yaw ) , sp . cos ( yaw ) , 0 ] ,
[ 0 , 0 , 1 ] ] )
return matrix_yaw * matrix_pitch * matrix_roll
def quat_rotate ( q0 , q1 , q2 , q3 ) :
# make symbolic rotation matrix from quat
return sp . Matrix ( [ [ q0 * * 2 + q1 * * 2 - q2 * * 2 - q3 * * 2 , 2 * ( q1 * q2 + q0 * q3 ) , 2 * ( q1 * q3 - q0 * q2 ) ] ,
[ 2 * ( q1 * q2 - q0 * q3 ) , q0 * * 2 - q1 * * 2 + q2 * * 2 - q3 * * 2 , 2 * ( q2 * q3 + q0 * q1 ) ] ,
[ 2 * ( q1 * q3 + q0 * q2 ) , 2 * ( q2 * q3 - q0 * q1 ) , q0 * * 2 - q1 * * 2 - q2 * * 2 + q3 * * 2 ] ] ) . T
def quat_matrix_l ( p ) :
return sp . Matrix ( [ [ p [ 0 ] , - p [ 1 ] , - p [ 2 ] , - p [ 3 ] ] ,
[ p [ 1 ] , p [ 0 ] , - p [ 3 ] , p [ 2 ] ] ,
[ p [ 2 ] , p [ 3 ] , p [ 0 ] , - p [ 1 ] ] ,
[ p [ 3 ] , - p [ 2 ] , p [ 1 ] , p [ 0 ] ] ] )
def quat_matrix_r ( p ) :
return sp . Matrix ( [ [ p [ 0 ] , - p [ 1 ] , - p [ 2 ] , - p [ 3 ] ] ,
[ p [ 1 ] , p [ 0 ] , p [ 3 ] , - p [ 2 ] ] ,
[ p [ 2 ] , - p [ 3 ] , p [ 0 ] , p [ 1 ] ] ,
[ p [ 3 ] , p [ 2 ] , - p [ 1 ] , p [ 0 ] ] ] )
def sympy_into_c ( sympy_functions ) :
from sympy . utilities import codegen
routines = [ ]
for name , expr , args in sympy_functions :
r = codegen . make_routine ( name , expr , language = " C99 " )
# argument ordering input to sympy is broken with function with output arguments
nargs = [ ]
# reorder the input arguments
for aa in args :
if aa is None :
nargs . append ( codegen . InputArgument ( sp . Symbol ( ' unused ' ) , dimensions = [ 1 , 1 ] ) )
continue
found = False
for a in r . arguments :
if str ( aa . name ) == str ( a . name ) :
nargs . append ( a )
found = True
break
if not found :
# [1,1] is a hack for Matrices
nargs . append ( codegen . InputArgument ( aa , dimensions = [ 1 , 1 ] ) )
# add the output arguments
for a in r . arguments :
if type ( a ) == codegen . OutputArgument :
nargs . append ( a )
#assert len(r.arguments) == len(args)+1
r . arguments = nargs
# add routine to list
routines . append ( r )
[ ( c_name , c_code ) , ( h_name , c_header ) ] = codegen . get_code_generator ( ' C ' , ' ekf ' , ' C99 ' ) . write ( routines , " ekf " )
getting ready for Python 3 (#619)
* tabs to spaces
python 2 to 3: https://portingguide.readthedocs.io/en/latest/syntax.html#tabs-and-spaces
* use the new except syntax
python 2 to 3: https://portingguide.readthedocs.io/en/latest/exceptions.html#the-new-except-syntax
* make relative imports absolute
python 2 to 3: https://portingguide.readthedocs.io/en/latest/imports.html#absolute-imports
* Queue renamed to queue in python 3
Use the six compatibility library to support both python 2 and 3: https://portingguide.readthedocs.io/en/latest/stdlib-reorg.html#renamed-modules
* replace dict.has_key() with in
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#removed-dict-has-key
* make dict views compatible with python 3
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#dict-views-and-iterators
Where needed, wrapping things that will be a view in python 3 with a list(). For example, if it's accessed with []
Python 3 has no iter*() methods, so just using the values() instead of itervalues() as long as it's not too performance intensive. Note that any minor performance hit of using a list instead of a view will go away when switching to python 3. If it is intensive, we could use the six version.
* Explicitly use truncating division
python 2 to 3: https://portingguide.readthedocs.io/en/latest/numbers.html#division
python 3 treats / as float division. When we want the result to be an integer, use //
* replace map() with list comprehension where a list result is needed.
In python 3, map() returns an iterator.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* replace filter() with list comprehension
In python 3, filter() returns an interatoooooooooooor.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* wrap zip() in list() where we need the result to be a list
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-zip
* clean out some lint
Removes these pylint warnings:
************* Module selfdrive.car.chrysler.chryslercan
W: 15, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 16, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 25, 0: Unnecessary semicolon (unnecessary-semicolon)
************* Module common.dbc
W:101, 0: Anomalous backslash in string: '\?'. String constant might be missing an r prefix. (anomalous-backslash-in-string)
************* Module selfdrive.car.gm.interface
R:102, 6: Redefinition of ret.minEnableSpeed type from float to int (redefined-variable-type)
R:103, 6: Redefinition of ret.mass type from int to float (redefined-variable-type)
************* Module selfdrive.updated
R: 20, 6: Redefinition of r type from int to str (redefined-variable-type)
old-commit-hash: 9dae0bfac4e54ec2b2e488d2b4ead1495c8f56d8
6 years ago
c_code = ' \n ' . join ( x for x in c_code . split ( " \n " ) if len ( x ) > 0 and x [ 0 ] != ' # ' )
c_header = ' \n ' . join ( x for x in c_header . split ( " \n " ) if len ( x ) > 0 and x [ 0 ] != ' # ' )
return c_header , c_code