Show last authors
1 (% class="row" %)
2 (((
3 (% class="col-xs-12 col-sm-8" %)
4 (((
5 (% class="jumbotron" %)
6 (((
7 (% class="container" %)
8 (((
9 = ,,Abstract,, =
10
11 Autonomous vehicles have become a vital part of the modern-day automotive industry that is looking for technologies which can improve and very well ensure the safety and well-being of humanity. In order to make a vehicle fully autonomous, attaining Drive-by-Wire (DbW) control is considered the initial step. In this project the DbW controls for a 2018 Toyota Prius has been developed using the comma.ai hardware, which is used to communicate with the vehicle and can be implemented and tested using a personal computer and joystick. The motivation for this project is to replace the existing system which is costly, bulky and most of the system components are proprietary of some company and furthermore not an open-source. Once the DbW controller is working, then it will make the transition to full autonomy easier.
12
13 The main objective of this project is to actually test the by-wire capabilities of the car using a general purpose computer and joystick along with the help of comma.ai hardware which is helping us to communicate with the vehicle’s ECUs by hacking into the CAN bus. The project focuses on the functional safety, design and development of a high level system architecture, component implementation and integration.
14 )))
15 )))
16
17 = **Introduction** =
18
19 In a modern day vehicle, with all the advances in electronic control technologies, the vehicle control has been shifting from mechanical systems to electronically controlled subsystems. Electronic control systems are increasingly used by the automotive industry to assist the driver or automate certain maneuvers of the vehicle. This move to partially automate the function of a vehicle has created the opportunity for computer-controlled systems to increase the efficiency of the vehicle's longitudinal and lateral control that ensures safety along with aiding driving comfort. These systems that aid advanced driver assistance also known as ADAS are common in most of the modern vehicles. Further technologies of ADAS that can be seen in several high-end vehicles such as Park-Assist, Adaptive Cruise Control (ACC), Lane Keeping Assist System (LKAS) allow electronic systems to take control of certain functions of the vehicle and use sensor feedback to control action taken by electronic control systems. All these functionalities can be considered to be stepping stones to reaching a fully autonomous vehicle.
20
21 Self-driving or autonomous vehicles are considered the future of transportation and artificial intelligence technologies will be required to reach their fruition. All major automakers around the world are investing enormously in improving autonomous vehicle technologies. An autonomous vehicle is fundamentally any vehicle that can move from one point to another without human intervention. One of the key prerequisites for a semi/ fully autonomous vehicle is the Drive-by-Wire (DbW) system. DbW technology allows functions in the vehicle that were formerly performed or controlled by mechanical transfer of forces to be controlled electronically. The technology replaces the traditional mechanical control systems with electronic control systems using electromechanical actuators and human machine interfaces. Once the vehicle’s longitudinal and lateral movement control can be attained using a by wire system, we are getting closer to realizing the final objective of driving the vehicle fully autonomously.
22
23 Through this project Eindhoven University of Technology expects to design and develop DbW controls for a 2018 model Toyota Prius with a joystick, a general purpose computer along with comma.ai hardware which includes a universal car interface called Panda and an adapter board called giraffe. In the following section a short description of all the hardware and software that was used in this project has been given.
24
25 == //**Background and context**// ==
26
27 The DbW controller project is a new tailored project that has been introduced to the PDEng Automotive Systems Design team of 2018. The challenge presented to the team is to start from scratch including the functional safety study, design and development of the high level system architecture, planning and implementation, and all of this to be accomplished within a very limited amount of time.
28
29 The ASD team of 2018 consisted of seven people with different technical and academic backgrounds. The team has one project manager and two team leaders. The project manager was also assigned the role of a team leader. The remaining five members were divided among the two team leaders. One team focused on the functional safety and the other team focused on the technical design and implementation. Both the teams worked in parallel during the entire project. The team has organized as follows.
30
31 |**Name**|**Role**|**Contact**
32 |(% colspan="3" %)**//Functional Safety Team//**
33 |Momen Abdallatif|Project Manager/ Team Leader|__[[m.a.h.abdallatif@tue.nl>>path:mailto:m.a.h.abdallatif@tue.nl]]__
34 |Dhruv Jagga|Designer|__[[d.jagga@tue.nl>>path:mailto:d.jagga@tue.nl]]__
35 |Akshay Pakkath|Designer|__[[a.pakkath@tue.nl>>path:mailto:a.pakkath@tue.nl]]__
36 |Salih Yousif|Designer|__[[s.e.a.yousif@tue.nl>>path:mailto:s.e.a.yousif@tue.nl]]__
37 |(% colspan="3" %)**//Technical Design Team//**
38 |Ashton Menezes|Team Leader/Designer|__[[a.a.menezes@tue.nl>>path:mailto:a.a.menezes@tue.nl]]__
39 |Achyuthan Sundarrajan|Designer|__[[a.sundarrajan@tue.nl>>path:mailto:a.sundarrajan@tue.nl]]__
40 |Varun Khattar|Designer|__[[v.khattar@tue.nl>>path:mailto:v.khattar@tue.nl]]__
41
42 == //**Goal**// ==
43
44 The main goal of this project is to test the by-wire capabilities of the given 2018 model Toyota Prius. In order for this, a system has to be developed that can perform the DbW operation on the car and to come up with functional safety requirements for the DbW controller by performing a Hazard Analysis and Risk Assessment (HARA) and Failure Mode Effect Analysis (FMEA), developing a high-level system architecture, in which the functional safety requirements are implemented.
45
46 = **System Description** =
47
48 The DbW controller system communicates with the vehicle in a safe way enabling the user to talk to specific vehicle ECUs (LKAS & ACC) which will further facilitate to take control of the vehicle’s lateral and longitudinal movement. The system is installed in a 2018 Toyota Prius with Adaptive Cruise Control and Lane Keeping Assist System. The system acts as a gateway between an application and the low-level vehicle systems.
49
50 For the implementation of this project, a joystick, a personal computer, a USB cable, comma.ai hardware and finally the Robot Operating System (ROS) running on Linux and the Python programming language, both of which are installed in the personal computer has been used. The comma.ai hardware enables us to hack into the vehicle’s CAN bus which allows us to read and write CAN messages. A short description of the functions of all the hardware and software used in this project can be seen below,
51
52 == //**Panda**// ==
53
54 The comma Panda is a universal car interface that enables communication to the car over USB and Wi-Fi.
55
56 == //**Giraffe**// ==
57
58 The comma Giraffe is an adapter board which acts as a fake On Board Diagnostics (OBD) port that help us to write and read CAN messages to and from the vehicle’s CAN buses that are not exposed on the on the main OBD connector.
59
60 == //**ROS**// ==
61
62 The entire communication within our system is managed by **ROS** which is a robust, general purpose mechanism for creating applications for robotics. For this project Kinetic version of ROS has been used. All the necessary information is present in the form of different channels called ROS topics and processing this information from different channels is done using ROS nodes.
63
64 == //**Python**// ==
65
66 Python is an interpreted, high-level, general-purpose programming language. Python has a design philosophy that emphasizes code readability, notably using significant whitespace.
67
68 == //**Joystick**// ==
69
70 The joystick used is a regular gaming controller with a D-pad or an analogue stick. The controller used in the system is a Logitech gamepad F310 that connects to the PC through USB 2.0.
71
72 == //**Computer**// ==
73
74 The PC is any desktop or laptop computer that runs Ubuntu 16.04. The ROS (version Kinetic) runs on top of it.
75
76 == //**USB**// ==
77
78 USB is an industry standard that establishes specifications for cables, connectors and protocols for connection, communication and power supply between personal computers and their peripheral devices.
79
80 == //**CAN**// ==
81
82 A CAN bus is a robust vehicle bus standard designed to allow micro-controllers and devices to communicate with each other in applications without a host computer.
83
84 = **Implementation** =
85
86 == //**CAN**// ==
87
88 The CAN network of the Toyota Prius has 5 separate buses, each of which is intended for specific functions (and hence each channel will carry CAN messages related to its function). The primary bus has the highest number of ECUs connected to it, followed by the powertrain CAN and the park-assist CAN buses. The last two are of primary interest to the project because the lateral and longitudinal movement of the car is controlled by communication in those channels. While the OBD port of the vehicle is present in the primary CAN bus (thereby providing access to a lot of information), the autonomous driving functionality is almost always on the park-assist bus. This is so because the ECUs corresponding to the autonomous systems always work on a higher level than the ECUs that work on the car’s basic systems. For example, the lane keep assist ECU or the cruise control ECU operate on a higher level, receive and send messages about vehicle speed, steering angle, etc. from an ECU that works on a lower level and directly controls the engine or brakes or power steering system. Thus, it also means that any damage to the higher-level functionalities will not affect the lower level functions because the latter are more fundamental and hence, more important.
89
90
91 [[image:image-20190405140705-1.png]]
92
93 //CAN architecture for 2010 model Toyota Prius //** **
94
95 It can be seen from the figure that the autonomous driving activity is associated with a CAN bus that is physically isolated from the low-level ECUs that directly control the car’s physical systems. The Drive Support ECU and the PMC ECU act as a sort of gatekeepers that abstract certain messages between the different channels, and only relevant messages can be seen on either bus. This can be partly attributed to hardware constraints of the protocol, where the number of unique message IDs on a channel is limited. While the nomenclature for the ECUs vary between OEMs and variants of the car (the terminology used is specific to the vehicle), here the DLC3 is used to denote the OBD-2 port.
96
97 In general, the pins 6 and 14 of the OBD-2 port are used for CAN. The standard set for the port mandates that it is the high-speed CAN, so its data rate will be 500 kbps. Based on the car manufacturer, the OBD port may also feature other communication protocols on other pins, or even another CAN channel. So, to make use of this port for CAN communication, the CAN messages are to be received by a device that reads CAN signals and encode them into meaningful data. Also, in the context of this project, the CAN data should be read and used by a computer, so they should be communicated through a port present in the PC. Hence an OBD to USB converter does the job perfectly. The handling of the data sent to the USB port is taken care of by dedicated software, or by user programs that read the serial input (USB is basically serial communication, and hence can be used by python code running on top of the OS). The device of choice here is a panda bridge from comma.ai, which is capable of bridging CAN and USB communication standards. It has an OBD-2 male port to USB 2.0 female port. It converts standard high-speed CAN bus data to serial USB data that can be read by programs running on top of an OS (USB driver -> OS -> custom software).
98
99 The panda bridge device can read the messages on the CAN channel to which it is connected to, however, in order to write messages onto the CAN bus, additional hardware is used. The giraffe adapter helps augment the basic functionality of the panda (which is reading the bus) with blocking the channel (which is similar to unplugging the panda), and passing the signals through panda. It does so with the help of hardware switches, which help configure the giraffe’s operating mode. It has a male and a female OBD-2 port, to accommodate the panda and to connect to the car’s diagnostic port. It also has an Ethernet port that has access to CAN1, CAN2, ignition detect, +12v, and ground. The giraffe is more of a passive device in the context of the project as soon as duplex communication mode is set.
100
101 The PC side of the system has the Ubuntu distribution of the Linux operating system running on the hardware, ROS running on Linux, and python code running on top of ROS. Hence the hardware requirement for Ubuntu 16.04 is 2 GHz dual core processor or better, 2 GB system memory, 25 GB of free hard drive space. The hardware requirement for ROS is 2 GB RAM, and a 1.6 GHz processor minimum. Linux has CAN support built-in to the kernel via SocketCAN. So that can be utilised by python files running on top of the OS to work on CAN. The primary python files, in the context of ROS, are called nodes. Nodes in ROS perform a self-contained and specific purpose. There are multiple assisting or auxiliary files, where function definitions, file-access and OS interaction are taken care of. The nodes and files associated with CAN operations are explained below.
102
103 == //**ROS**// ==
104
105 In the figure below, the square boxes represent topics and the circles represent nodes. Information exchange between nodes takes place through topics. A node sends messages under a topic.
106
107 [[image:image-20190405173528-1.png]]
108
109 **~ // //**// ROS Architecture//
110
111 **__Writing messages to the CAN bus:__** There are two basic CAN messages which have to be generated by the joystick: steering and acceleration. The joystick is used to give input to the PC with ROS installed on it. This input is given to nodes //Joy_to_acc// and //Joy_to_steer// under the topic ///joy//. These nodes publish the topics //Steer_amount// and //Acc_amount//. For example, the function for calculating the acceleration amount:
112
113 (% class="box infomessage" %)
114 (((
115 class JoyToAcc(object):
116 def ~_~_init~_~_(self):
117 **# publishing the steering torque**
118 self.pub_steering = rospy.Publisher('/steering_amount', Int16, queue_size=1)
119 **# publishing the acceleration amount**
120 self.pub_acc = rospy.Publisher('/acc_amount', Int16, queue_size=1)
121 **# subscribing to the input from the joystick**
122 self.sub = rospy.Subscriber('/joy', Joy, self.joy_cb, queue_size=1)  
123
124 def joy_cb(self, data):
125 left_right = data.axes[0] * -1.0
126 up_down = data.axes[4] * -1.0
127 print data.axes
128
129 **~ # calculating the acceleration amount from the joystick input**
130 **~ **amount_acc = int(up_down * 1023)
131 if amount_acc < 0:
132 amount_acc = 0
133 if amount_acc > 1023:
134 amount_acc = 1023
135 self.pub_acc.publish(amount_acc)
136
137 # **calculating the steering torque from the joystick input**
138
139 amount_steer = int(left_right * 3840)
140 self.pub_steering.publish(amount_steer)
141 print("amount_steer: " + str(amount_steer))
142 print("amount_acc: " + str(amount_acc))
143 )))
144
145 (% class="wikigeneratedid" %)
146 The All sender node subscribes to these topics and publishes the messages under the topic //Panda board//. These are sent by the Panda through the Giraffe to the CAN bus of the car.
147
148 (% class="box infomessage" %)
149 (((
150 class AllPublisher(object):
151 def ~_~_init~_~_(self):
152 self.p = Panda()
153 self.p.set_safety_mode(self.p.SAFETY_ALLOUTPUT)
154 self.acc_val = 0
155 self.steer_val = 0
156 **# subscribing to the acceleration amount**
157 self.sub_acc = rospy.Subscriber('/acc_amount', Int16, self.acc_cb, queue_size=1)
158 **# subscribing to the steering torque**
159 self.sub_steer = rospy.Subscriber('/steering_amount', Int16, self.steer_cb, queue_size=1)               
160
161 def acc_cb(self, data):
162 print("acc_cb: " + str(data))
163 **# setting the maximum and minimum value of the acceleration**
164 if data.data > 1023:
165 self.acc_val = 1023
166 elif data.data < -1023:
167 self.acc_val = -1023
168 self.acc_val = data.data
169
170 def steer_cb(self, data):
171 print("steer_cb: " + str(data))
172 **# setting the maximum and minimum value of the steering torque**
173 if data.data > 3840:
174 self.steer_val = 3840
175 elif data.data < -3840:
176 self.steer_val = -3840
177 self.steer_val = data.data
178 )))
179
180 **Creation of CAN messages**
181
182 (% class="wikigeneratedid" %)
183 There is a long hierarchy of functions used to create a CAN message. The highest level functions used to make the steering and acceleration commands use the packer file which uses the class CANPacker e.g. for making the steering command, the following function is used:
184
185 (% class="box infomessage" %)
186 (((
187 def create_steer_command(packer, steer, steer_req, raw_cnt):         
188
189 """Creates a CAN message for the Toyota Steer Command."""
190
191 values = {
192
193 **# steering request can have 0 or 1 as value**
194 **~ **"STEER_REQUEST": steer_req,**      **
195
196 **# the amount of steering torque  
197 **"STEER_TORQUE_CMD": steer,
198 "COUNTER": raw_cnt,
199 "SET_ME_1": 1,
200 }
201 **~ # creating the steering command using the packer file**
202 **~ **return packer.make_can_msg("STEERING_LKA", 0, values) 
203 )))
204
205 (% class="wikigeneratedid" %)
206 The function //make_can_msg// uses another function called //pack_bytes//:
207
208 (% class="box infomessage" %)
209 (((
210 def make_can_msg(self, addr, bus, values, counter=-1):
211 **# calling the pack_bytes function**
212 addr, msg = self.pack_bytes(addr, values, counter)
213 return [addr, 0, msg, bus]
214 )))
215
216 (% class="wikigeneratedid" %)
217 The function //pack_bytes// appends the variables together using both the defined and built in //pack// functions:
218
219 (% class="box infomessage" %)
220 (((
221 def pack_bytes(self, addr, values, counter=-1):
222 addr, size = self.name_to_address_and_size[addr]
223
224 **# calling the pack function**
225 **~ **val = self.pack(addr, values, counter)
226 r = struct.pack(">Q", val)
227 return addr, r[:size]
228 )))
229
230 (% class="wikigeneratedid" %)
231 The //pack// function is defined as:
232
233 (% class="box infomessage" %)
234 (((
235 def pack(self, addr, values, counter):
236 values_thing = []
237 for name, value in values.iteritems():
238 if name not in self.sig_names:
239 **# using the imported ffi package**
240 self.sig_names[name] = ffi.new("char[]", name)     
241
242 values_thing.append({
243 'name': self.sig_names[name],
244 'value': value
245 })
246
247 values_c = ffi.new("SignalPackValue[]", values_thing)
248
249 return libdbc.canpack_pack(self.packer, addr, len(values_thing), values_c, counter)
250 )))
251
252 (% class="wikigeneratedid" %)
253 The package //libdbc// is defined as:
254
255 (% class="box infomessage" %)
256 (((
257 import os
258 import subprocess
259
260 from cffi import FFI
261
262 can_dir = os.path.dirname(os.path.abspath(~_~_file~_~_))
263 libdbc_fn = os.path.join(can_dir, "libdbc.so")
264 subprocess.check_call(["make"], cwd=can_dir)
265
266 ffi = FFI()
267 ffi.cdef()
268
269 libdbc = ffi.dlopen(libdbc_fn)
270 )))
271
272 **__Reading CAN messages from the CAN bus__**
273
274 (% class="wikigeneratedid" %)
275 CAN messages from the CAN bus are read through Panda by a node called //can_bridge// which subscribes to messages under the topic //Send_Can_messages// and publishes them under a topic called //Can_frame_messages//.
276
277 (% class="box infomessage" %)
278 (((
279 class PandaBridgePub(object):
280 def ~_~_init~_~_(self, rate=1000):
281 **# establishing node as publisher of CAN frame messages**
282 self.can_pub = rospy.Publisher('can_frame_msgs', Frame, queue_size=10)
283 rospy.loginfo("Setting up publisher to: " +
284 str(self.can_pub.resolved_name))
285 self.rate = rate
286 rospy.loginfo("Reading from panda board at " + str(self.rate) + " Hz.")
287 rospy.loginfo("Connecting to Panda board...")
288
289
290 **# using Panda class from the Panda library**
291 **~ ** self.panda = Panda()
292 rospy.loginfo("Setting safety mode to SAFETY_ALLOUTPUT")
293 self.panda.set_safety_mode(self.panda.SAFETY_ALLOUTPUT)
294 self.to_send_msgs = []
295
296 **# establishing node as subscriber of CAN messages from the Panda**
297 **~ **self.can_sub = rospy.Subscriber('send_can_msg', Frame, self.can_cb,
298 queue_size=10)
299 rospy.loginfo("Connected.")
300
301 def can_cb(self, data):
302 self.to_send_msgs.append(data)
303
304 def run(self):
305 rate = rospy.Rate(self.rate)
306 while not rospy.is_shutdown():
307
308 **# Reading gives us up to 256 messages**
309 can_msg_block = self.panda.can_recv()
310 **# print can_msg_block
311 # A message looks like:
312 # [(420, 55639, bytearray(b'\x00f\x00\x00\x00\x00\x00:'), 0),
313 # (428, 55761, bytearray(b'\x7f\xff\x00\x00\x00\x08\x002:'), 0),# ... ]**
314
315 if can_msg_block:
316 self.process_msg_block(can_msg_block)
317
318 if self.to_send_msgs:
319 **# copying current msgs to send and reset buffer**
320 msgs = self.to_send_msgs[:]
321 self.to_send_msgs = []
322
323 **# sending all messages**
324 **~ **for msg in msgs:
325 self.send_can_msg(msg)
326
327 rate.sleep()
328 )))
329
330 (% class="wikigeneratedid" %)
331 The CAN frame messages are converted into a readable format for humans i.e. in a dictionary like format with topic string by a node called //frame_decoder//.
332
333 (% class="box infomessage" %)
334 (((
335 class FrameDecoder(object):
336 def ~_~_init~_~_(self):
337 rp = RosPack()
338 pkg_path = rp.get_path('panda_bridge_ros')
339 self.can_msg_parser = load_dbc_file(pkg_path + '/config/' + 'honda_civic_touring_2016_can_for_cantools.dbc')
340
341
342 **# setting node as a publisher of messages in human friendly format**
343
344 **~ ** self.pub = rospy.Publisher('can_frame_msgs_human_friendly', String,queue_size=10)
345
346 **# setting node as a subscriber to CAN frame messages  **
347
348 **~ **self.frame_sub = rospy.Subscriber('can_frame_msgs', Frame,self._cb, queue_size=10)
349 self.msg_id_to_msg_name = {}
350 understood_msgs = []
351 for msg in self.can_msg_parser.messages:
352 this_msg = {}
353 this_msg['frame_id'] = msg.frame_id
354 this_msg['name'] = msg.name
355 this_msg['signals'] = msg.signals
356 this_msg['nodes'] = msg.nodes
357 understood_msgs.append(this_msg)
358 self.msg_id_to_msg_name[msg.frame_id] = msg.name
359
360 rospy.loginfo("To interpret the messages:")
361 pp = PrettyPrinter()
362 rospy.loginfo(pp.pformat(understood_msgs))
363
364 def _cb(self, data):
365 try:
366 msg = self.can_msg_parser.decode_message(data.id, data.data)
367 msg['frame_id'] = data.id
368 msg['message_name'] = self.msg_id_to_msg_name[data.id]
369 msg['raw_msg'] = str(data.data)
370 human_friendly = str(msg)
371 **# string will look like:
372 # {'message_name': 'STEERING_CONTROL', 'CHECKSUM': 5, 'COUNTER': 1,
373 # 'STEER_TORQUE': 0, 'frame_id': 228, 'SET_ME_X00': 0,
374 # 'raw_msg': '\x00\x00\x00\x00\x15\x00\x00\x00',
375 # 'STEER_TORQUE_REQUEST': 0, 'SET_ME_X00_2': 0}**
376 except KeyError:
377 msg = {}
378 msg['frame_id'] = data.id
379 msg['message_name'] = "UNKNOWN_MESSAGE"
380 msg['raw_msg'] = str(data.data)
381 human_friendly = str(msg)
382 except ValueError:
383 msg = {}
384 msg['frame_id'] = data.id
385 msg['message_name'] = "UNKNOWN_MESSAGE"
386 msg['raw_msg'] = str(data.data)
387 human_friendly = str(msg)
388
389 self.pub.publish(human_friendly)
390 )))
391
392 (% class="wikigeneratedid" %)
393 The CAN frame messages are also converted to twist type messages, a format readable by ROS, by a node called //listener//. Twist type messages give information about wheel speed and wheel angle to ROS.
394
395 (% class="box infomessage" %)
396 (((
397 class TwistFromCan(object):
398 **# Constants**
399 WHEEL_SPEEDS_MSG_ID = 170
400
401 KINEMATICS_MSG_ID=36
402
403 def ~_~_init~_~_(self):
404 rospy.loginfo("Initializing TwistFromCan")
405 rp = RosPack()
406 pkg_path = rp.get_path('panda_bridge_ros')
407
408 **# ensure that the dbc file is in the correct folder**
409 **~ ** path_to_dbc = pkg_path + '/opendbc/toyota_prius_2017_pt_generated.dbc'
410 self.can_db = cantools.db.load_file(path_to_dbc)
411 self.wheel_speed = None
412 self.yaw_rate = None
413
414 **# setting node as a subscriber to can_frame_messages**
415 **~ **self.sub = rospy.Subscriber("can_frame_msgs", Frame,self.callback, queue_size=10)**  
416 # setting node as a publisher of twist messages**
417 **~ **self.pub = rospy.Publisher("twist_stamped",TwistStamped, queue_size=10)
418 rospy.loginfo("Done")
419
420 def callback(self, msg):
421 msgID = msg.id
422 if (msgID == self.WHEEL_SPEED_MSG_ID):
423 data = self.can_db.decode_message(msgID, msg.data)
424 speed_RL = data['WHEEL_SPEED_FL']
425 speed_RR = data['WHEEL_SPEED_FR']
426 self.wheel_speed = (speed_RL + speed_RR) / 2.0
427
428 if (msgID == self.KINEMATICS_MSG_ID):
429 data = self.can_db.decode_message(msgID, msg.data)
430 self.yaw_rate = data['YAW_RATE']
431 )))
432
433 = **Modeling of a Supervisor for DbW System** =
434
435 In this section, the plant of DbW system was modeled in Compositional Interchange Format (CIF) 3.0 platform. Overall system automaton was designed using the automatons of subsystems. These automatons consist of states of the plant, a relevant transition can be made in between these states depending upon the trigger of desired events. These subsystems interact with one another to achieve the desired overall system functionality. Later, a supervisory controller was designed for this plant by writing specific requirements coming from the high-level design document and the functional safety document. These requirements put constraints on the system functionality to avoid the conflicting states of the subsystems to be active at the same time and hence ensure system safety. To model the DbW system several plants were identified as follows:
436
437 == //**Vehicle State**// ==
438
439 The vehicle has two states, one is a manual operating state (**Manual**) in which all the system functionality is controlled by the driver. Another state is system active state (**DBW_Active**) in which all the system functionality is controlled using the joystick by the operator. The state transition diagram for this plant is shown in Figure 3.
440
441 [[image:image-20190415102656-1.png]]
442
443 **~ **// Automaton of Vehicle//
444
445 == //**System State**// ==
446
447 The identified system is DbW system which has three states. The system is initialized in OFF state (**OFF**) keeping the vehicle state in manual operating state. Another system state (**Checking**) allows, making all possible checks required to safely switch on the system. When all these checks are carried out, then only the system can be in the running state (**Running**). The state transition diagram for this plant is shown in Figure 4.
448
449 [[image:image-20190415103149-2.png]]
450
451 // Automaton of DbW System//
452
453 == //**ON-OFF Button State**// ==
454
455 Another identified plant is the ON-OFF button. The possible states for this plant are on (**ON**) and off (**OFF**). The state transition diagram for the plant is shown in Figure 5.
456
457 [[image:image-20190415103149-3.png]]
458
459 **~ **//Automaton of ON-OFF Button//
460
461 == //**ROS State**// ==
462
463 Robot-operating-system (ROS) has three states. It is initialized from the off state (**OFF**) and can have two more functional states. One of these states is a read-only state (**Reading**) in which system is only allowed to read the CAN Bus and another is read and write state (**Reading_Writing**). In this state, the system can read data and write data on the CAN Bus. The ROS is only allowed to be in the read and write state if all the safety requirements are always fulfilled. The state transition diagram for this plant is shown in Figure 6.
464
465 [[image:1555317194645-683.png]]
466
467 **~ **//Automaton of Ros//
468
469 == //**ECUs State**// ==
470
471 There are two ECUs considered within the scope of the project, the states for the functionality of these ECUs are recognized to be the same which is either the ECU is in working state (**OK**) or in a state of fault (**Not_OK**). The state transition diagram for this plant is shown in Figure 7.
472
473 [[image:image-20190415103312-5.png]]
474
475 **~ **// Automaton of ECU//
476
477 == //**Emergency (EM) Button State**// ==
478
479 The emergency button provides the functionality of shifting entire control over the system from the joystick to the driver, instantaneously. The EM Button can have two states, either pressed (**Pressed**) or released (**Released**). The state transition diagram for this plant is shown in Figure 8.
480
481 [[image:1555317291096-741.png]]
482
483 // Automaton of EM Button//
484
485 == //**Communication Channel State**// ==
486
487 The communication channel includes the hardware from comma.ai (Panda and Giraffe) and the vehicle CAN Bus. If all the connections are intact and messages are received to ROS with proper integrity, then the communication channel is in healthy state (**Good_Health**) otherwise it is in a bad state of health (**Bad_Health**). The state transition diagram for this plant is shown in Figure 9.
488
489 [[image:1555317331714-290.png]]
490
491 **~ **//Automaton of Communication Channel//
492
493 == //**Supervisor**// ==
494
495 Using the modeling in CIF 3.0, supervisory control is synthesized for the overall Drive-by-Wire functionality which will allow the system to make transitions in safe-states. Without the supervisory control, the subsystems in DbW model can be in any state. Thus, the system model is designed as maximal permissive. Not all of these states are desirable all the times to perform relevant system functions. The transition to these undesirable states can be prevented by creating requirements. These requirements are defined further in this section.
496
497 (% class="wikigeneratedid" id="HRequirementsfortheactivationofDbWsystem" %)
498 //**Requirements for the activation of DbW system**//
499
500 * To initiate the system (**initiate_system**) it is required that the ON-OFF Button must be in **Button_on** state.
501 * In the activation mode of the system, the ROS can be in **Reading** state only when the system status is in **Checking** state, the vehicle is in **Manual** state and ON-OFF Button is in **Button_on** state.
502 * In the activation mode of the system, the ROS is allowed to be in **Reading_Writing** state only when the system status is in **Running** state, the vehicle is in **DbW_Active** state, ON-OFF Button is in **Button_on** state, all ECUs are in **OK** state, EM Button is **Released** and the communication channel is in **Good_Health.**
503
504 (% class="wikigeneratedid" id="HRequirementsforthedeactivationofDbWsystem" %)
505 //**Requirements for the deactivation of DbW system**//
506
507 * Deactivation of DbW is only possible when system status is in **Running** state.
508 * The system must terminate when ON-OFF Button is in **Button_Off** state.
509 * ROS must go to **OFF** state when ON-OFF Button is in **Button_Off** state.
510
511 (% class="wikigeneratedid" id="HRequirementfortheEmergencyStoporManualOverride" %)
512 //**Requirement for the Emergency Stop or Manual Override**//
513
514 * Deactivation of DbW is allowed if EM Button is **Pressed**, ECUs are in bad health (**Not_OK**) or communication channel is in **Bad_Health**.
515
516 With these requirements in practice, the supervisor can trigger the controllable events in the model to ensure the desired functionality. The current supervisor can interact and control the states of several subsystems such as ROS, Vehicle and DbW System. The current requirements are sufficiently residing within the project scope, if required then the supervisor can be upgraded with more stringent requirements. The relationship of the supervisor with relevant subsystems is shown in Figure 10.
517
518 [[image:image-20190415103957-8.png]]
519
520 **~ **// Relationship between supervisor and modeled subsystems//
521
522 == //**Simulation**// ==
523
524 The simulation process is carried out on the modeled plant for the DbW system, with the constraints on the functionality of the plant designed as system requirements. The system functionality is checked first for the modeled plant without any restrictions/requirements. Then it was validated after synthesizing the supervisor with the requirements using the data-based synthesis tool within the CIF tool. GUI and state visualization is used to observe and validate system functionality. See Figure 11.  A video is also provided with this report with the simulation of this exercise.
525
526 [[image:1555317643701-278.png]]
527
528 **~ **// Simulation window with GUI input and state visualization//
529
530 == //**HMI**// ==
531
532 HMI is designed to observe the system state as shown in Figure 10.
533
534 [[image:image-20190415104111-10.jpeg]]
535
536 **~ **// HMI of DbW System in CIF 3.0 environment//
537
538 == **CIF Simulation Video** ==
539
540 {{video url="https://youtu.be/0hkY7smzbBg" attachment="CIF Simulation"/}}
541
542 = **Test Plan** =
543
544 == //**Overview**// ==
545
546 The DbW system being tested is operated by an operator through a joystick, in addition to a safety driver, who is present to take control of the vehicle in case of any failure. The system is used to control the longitudinal and lateral movement of a Toyota Prius 2018 when activated by the operator. The system components under consideration for testing are Giraffe, Panda, ROS PC, USB bus, HMI (including the joystick), Lane Keeping Assist System (LKAS) ECU and Adaptive Cruise Control (ACC) ECUs. Testing of the system individual components is outsourced to different vendors with guarantee on their functionalities separately, the test plan will focus on the integrated system functionalities.
547
548 == //**Test objectives**// ==
549
550 The objective of these tests is to confirm that the system can correctly perform the functions listed below under normal driving conditions. The functions are:
551
552 1. Steering through the joystick within the allowed latency.
553 1. Accelerating through the joystick within the allowed latency.
554 1. Steering and accelerating Simultaneous.
555 1. Activating brakes through the DbW system input within the allowed latency.
556 1. Transferring control to the driver when pressing the emergency stop button.
557 1. Warning in case of CAN bus failure, Giraffe/Panda failure, USB cable failure and joystick failure.
558 1. Showing the status of the system (On/Off) to the operator and driver.
559
560 == //**Test cases**// ==
561
562 === //**Test case 1: Steering functionality**// ===
563
564 **Purpose:** To verify that the vehicle steers as desired by the operator through the joystick steering input.
565
566 **Test procedure:**
567
568 1. Calibrate the sensors.
569 1. Give predetermined values of steering input through the joystick.
570 1. Read the measured steering angles from the vehicle steering sensor.
571
572 **Expected result:** The steering sensor should feedback the same steering angle as commanded by the tester.
573
574 === //**Test case 2: Vehicle response time to steering command**// ===
575
576 **Purpose:** To verify that the latency between giving the steering input and the actual vehicle response is within the determined timeframe.
577
578 **Test procedure:**
579
580 1. Give predetermined values of steering input through the joystick.
581 1. Document the time between giving the steering input and the start of actuation.
582 1. Document the time when actuation is done.
583
584 **Expected result:** The difference between inputting the steering command and the finish of actuation is within a TBD period.
585
586 === //**Test case 3: Acceleration functionality**// ===
587
588 **Purpose:** To verify that the vehicle accelerates as desired by the operator through the joystick acceleration input.
589
590 **Test procedure:**
591
592 1. Calibrate the sensors.
593 1. Give a predetermined set of values of acceleration input through the joystick.
594 1. Read the measured vehicle speed by the sensor.
595
596 **Expected result:** The measured speeds should correspond with the input values
597
598 === //**Test 4: Vehicle response time to acceleration command**// ===
599
600 **Purpose:** To verify that the latency between giving the acceleration input and the actual vehicle response is within the determined timeframe.
601
602 **Test procedure:**
603
604 1. Give a predetermined set of values of acceleration input through the joystick.
605 1. Document the time of the actuation start.
606 1. Document the time when actuation is done and vehicle reaches the set speed.
607
608 **Expected result:** The difference between the input of the acceleration command and the vehicle starting to accelerate is within the TBD period.
609
610 === //**Test case 5: Steering and acceleration inter-operation test**// ===
611
612 **Purpose:** To verify that the vehicle steers and accelerates simultaneously as desired by the operator through the joystick steering and acceleration input.
613
614 **Test procedure:**
615
616 1. Calibrate the sensors.
617 1. Give a predetermined set of values of steering input through the joystick while also giving a predetermined set of values of acceleration input simultaneously.
618 1. Read the measured vehicle speed by the sensor.
619 1. Read the measured steering angle by the vehicle steering sensor.
620
621 **Expected result:** The steering sensor and speed sensor should give readings of the same entered steering angles and speeds.
622
623 === //**Test case 6: Brake functionality**// ===
624
625 **Purpose:** To verify that the vehicle brakes as desired by the operator through the joystick brake input.
626
627 **Test procedure:**
628
629 1. Give 100% acceleration input through the joystick.
630 1. Read the measured vehicle speed by the sensor to confirm that the vehicle speed is 30 km/h.
631 1. Press brake button on the joystick until the vehicle is stationary.
632 1. Read the speed sensor measurement to confirm that the speed is 0 km/h.
633
634 **Expected result:** The vehicle should come from 30 km/h to a complete stop.
635
636 === //**Test case 7: Brakes response time**// ===
637
638 **Purpose: **To verify that the vehicle stops completely after receiving the command of maximum braking within TBD time.
639
640 **Test procedure:**
641
642 1. Give 100% acceleration input through the joystick.
643 1. Read the measured vehicle speed by the sensor to confirm that the vehicle speed is at 30 km/h.
644 1. Press brake button on the joystick until the vehicle is stationary.
645 1. Document the time when the button is pressed.
646 1. Read the sensor speed feedback.
647 1. Document the time when the vehicle starts to decelerate.
648
649 **Expected result: **The vehicle starts decelerating after pressing the brake button within the TBD period.
650
651 === //**Test case 8: Emergency button functionality**// ===
652
653 **Purpose: **To verify that the vehicle is controlled by the driver once the emergency button is pressed.
654
655 **Test procedure:**
656
657 1. Operator to give an acceleration input through the joystick.
658 1. Operator to give a steering input through the joystick.
659 1. Read steering and speed sensors feedback to confirm reaching the desired speed and steering angle.
660 1. Driver to press emergency button.
661 1. Confirm that vehicle is not controllable by joystick anymore.
662
663 **Expected result:** Vehicle control transfers to the driver; operator cannot control vehicle using joystick.
664
665 === //**Test case 9: Connection to CAN bus failure**// ===
666
667 **Purpose: **To verify that there will be warning in case of loss of information from the vehicle’s CAN bus.
668
669 Test procedure:
670
671 1. Confirm vehicle is at rest.
672 1. Confirm that the DbW system is active.
673 1. Unplug the CAN bus connection – Giraffe or Panda.
674 1. Check if there is a warning on the HMI.
675
676 **Expected result:** The HMI shows information loss warning once the bus is disconnected.
677
678 === //**Test case 10: Joystick failure**// ===
679
680 **Purpose:** To verify that the DbW system warns the operator and driver in case of the failure of the joystick.
681
682 **Test procedure:**
683
684 1. Set the vehicle speed to 0 km/h.
685 1. Confirm that the DbW system is active.
686 1. Unplug the joystick cable.
687 1. Check the HMI for warning.
688
689 **Expected result:** HMI shows warning signal of joystick failure once the joystick cable is unplugged.
690
691 === //**Test case 11: System activation and signaling (ON)**// ===
692
693 **Purpose: **To verify that the system will be activated and inform the driver and the operator about the status of the system (on).
694
695 **Test procedure:**
696
697 1. Activate the system.
698 1. Check the HMI for system status.
699
700 **Expected result:** once the system is activated, the HMI should signal that the system is on.
701
702 === //**Test case 12: System deactivation and signaling (Off)**// ===
703
704 **Purpose: **To verify that the system will be deactivated and inform the driver and the operator about the status of the system (off).
705
706 **Test procedure:**
707
708 1. Activate the system and check it is on
709 1. Press emergency button.
710 1. Check the status of the system in the HMI.
711
712 **Expected result**: Once the emergency button is pressed, HMI shows the system is off.
713
714 = **Conclusion and Recommendations** =
715
716 == //**Conclusion**// ==
717
718 The Drive-by-Wire functionality for Toyota Prius has been achieved using comma.ai hardware to read and write CAN messages, a joystick to control the vehicle and a computer running ROS. The CAN messages were encoded and decoded using a dbc-file and functions from openpilot; a github repository of comma.ai. A supervisor has also been implemented to incorporate the functional safety requirements and design the modes of operation for the system.
719
720 == //**Recommendations**// ==
721
722 The goal of this project was to read CAN and joystick information and thereby controlling the car by writing CAN messages to the CAN Bus, while also considering all the safety aspects. Based on the work which was done during this project and the results from the implementation, a list of recommendations are listed below.
723
724 * (((
725 Here a supervisor is designed to replicate how the system starts and behaves in case of emergency. This supervisor can be integrated with ROS and hardware features like HMI, emergency button and power button.
726 )))
727 * (((
728 Certain ROS nodes for different application could be clubbed into ROS service. This ROS service could be initiated either by the supervisor or by a higher level controller.
729 )))
730 * (((
731 CAN messages are published by the ECUs of the steering, engine and braking systems. It is required to know the health status of these ECUs at all times. A solution to this maybe to measure in real-time the frequency at which these messages are put on the CAN bus. This checking can be programmed in one of the ROS nodes by comparing the clock time of every consecutive message of an ECU.
732 )))
733 * (((
734 The system goes into reading mode when manual override is taken over by actuation of the steering wheel, brakes or the accelerator pedal. Our system has access only to the CAN bus of the vehicle. One of the major challenges here is to identify when a manual input is given to the above actuators. A solution to this problem may be to carry out specific tests like manual steering and read what signals are varying in the CAN bus. By doing this it is possible to identify what information is generated when a manual input is given.
735 )))
736
737 = **Manual for operating the System** =
738
739 This manual gives the procedure required to setup all the ROS nodes for running the System.
740
741 * While operating ROS it is necessary that the all the information is available to a node before activating this node (python Function).
742 * The system is divided into three functional parts, Reading CAN Messages, Reading the Joystick data and Writing CAN Messages.
743
744 //Note: All the commands are entered in terminal.//
745
746 == **//Instructions for Reading CAN Messages//** ==
747
748 |(% style="width:342px" %)Instructions|(% style="width:642px" %)Description
749 |(% colspan="2" %)**//Reading CAN Messages//**
750 |(% style="width:342px" %)(((
751 * Connect the Giraffe between the connector from the car and the front camera of the windscreen.
752 * Connect the USB cable from the Giraffe to the Panda Board.
753 * Plug in the panda board to the USB port of the laptop.
754 * Open terminal in the catkin folder.
755 * Run the command catkin_make
756 * Initiate ROS by running the command roscore in a Terminal.
757
758 * Type rosrun <package_name> panda_bridge_ros.py
759 * Type rostopic echo /frame_messages to validate
760
761 * Run the node Frame_Decoder in terminal using rosrun <package_name> frame_decoder.py.
762 * Type rostopic echo /human_friendly to validate
763
764 * Run the node can_listener_toyota in terminal using rosrun <package_name> can_listener_toyota.py
765 * Type rostopic echo /Twist to validate
766 )))|(% style="width:642px" %)(((
767 These steps  are required to have access to the CANBUS information in the vehicle. The Giraffe acts like junction box to tap information from this wire.
768
769
770
771
772
773 This compiles all the packages in the SRC folder.
774
775
776
777 This command activates a  node that creates an object that belongs to the Panda class. It publishes a topic “/frame_messages” using the information received from the Panda.
778
779
780
781
782 Make sure that in the code the path of the dbc file is correct. The frame decoder publishes the CAN messages into human readable format in a topic “/human_friendly” by subscribing to the frame messages topic.
783
784
785
786 Make sure that in the code the path of the dbc file is correct. The can_listener_toyota publishes twist messages by subscribing to “/frame_messages. Validate that the node is working by echoing the messages of the “/Twist” topic.
787 )))
788
789 == **//Instructions for Reading and Publishing Joystick Messages//** ==
790
791 |(% style="width:243px" %)Instructions|(% style="width:741px" %)Descriptions
792 |(% colspan="2" %)**//Reading Joystick Messages//**
793 |(% style="width:243px" %)(((
794 * Connect the joystick to the USB port of the laptop
795 * Setup the Joystick node
796 * Type rostopic echo /joy to validate
797
798 * Type rosrun <package> joy_to_acc.py
799 * Type rostopic echo /acceleartion to validate
800
801 * Type rosrun <package> joy_to_steer.py
802 * Type rostopic echo /steer to validate
803 )))|(% style="width:741px" %)(((
804 For setting up the joystick node which publishes to the topic /joy, follow in the instructions given in the ROS Wiki page [[http:~~/~~/wiki.ros.org/joy/Tutorials/ConfiguringALinuxJoystick>>url:http://wiki.ros.org/joy/Tutorials/ConfiguringALinuxJoystick]].
805
806
807
808
809 The joy_to_acc node publishes the /acceleration topic by subscribing to the /joy topic.
810
811
812
813 The joy_to_steer node publishes the /steer topic by subscribing to the /joy topic.
814 )))
815 |(% colspan="2" %)**//Publishing CAN Messages//**
816 |(% style="width:243px" %)(((
817 * Type rosrun <package> set_acc_steer.py
818 )))|(% style="width:741px" %)(((
819 This node creates an object of panda class. This object is used to feed messages into the panda. The integer information from the steering or the acceleration topic is converted  to can messages and published to the panda board.
820 )))
821 )))
822
823 (% class="col-xs-12 col-sm-4" %)
824 (((
825 (% class="box" %)
826 (((
827 = [[image:1554451298332-638.png]] =
828
829 |=Manufacturer|Toyota
830 |=Model|Prius
831 |=Year of manufacturing|2018
832 |=Image|[[Credits>>https://www.autoevolution.com/news/toyota-prius-prime-plug-in-gets-tuned-by-trd-and-modellista-in-japan-115519.html#agal_7]]
833 )))
834
835 (% class="box" %)
836 (((
837 **Contents**
838
839 {{toc/}}
840 )))
841 )))
842 )))

Need help?

If you need help with XWiki you can contact:

MPS Group