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,, =
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 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.
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 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 )))
17 = **Introduction** =
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.
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.
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 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.
25 == //**Background and context**// ==
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.
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.
31 |**Name**|**Role**|**Contact**
32 |(% colspan="3" %)**//Functional Safety Team//**
33 |Momen Abdallatif|Project Manager/ Team Leader|__[[>>]]__
34 |Dhruv Jagga|Designer|__[[>>]]__
35 |Akshay Pakkath|Designer|__[[>>]]__
36 |Salih Yousif|Designer|__[[>>]]__
37 |(% colspan="3" %)**//Technical Design Team//**
38 |Ashton Menezes|Team Leader/Designer|__[[>>]]__
39 |Achyuthan Sundarrajan|Designer|__[[>>]]__
40 |Varun Khattar|Designer|__[[>>]]__
42 == //**Goal**// ==
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.
46 = **System Description** =
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.
50 For the implementation of this project, a joystick, a personal computer, a USB cable, 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 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,
52 == //**Panda**// ==
54 The comma Panda is a universal car interface that enables communication to the car over USB and Wi-Fi.
56 == //**Giraffe**// ==
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.
60 == //**ROS**// ==
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.
64 == //**Python**// ==
66 Python is an interpreted, high-level, general-purpose programming language. Python has a design philosophy that emphasizes code readability, notably using significant whitespace.
68 == //**Joystick**// ==
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.
72 == //**Computer**// ==
74 The PC is any desktop or laptop computer that runs Ubuntu 16.04. The ROS (version Kinetic) runs on top of it.
76 == //**USB**// ==
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.
80 == //**CAN**// ==
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.
84 = **Implementation** =
86 == //**CAN**// ==
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.
91 [[image:image-20190405140705-1.png]]
93 //CAN architecture for 2010 model Toyota Prius //** **
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.
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, 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).
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.
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.
103 == //**ROS**// ==
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.
107 [[image:image-20190405173528-1.png]]
109 **~ // //**// ROS Architecture//
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:
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)  
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
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)
137 # **calculating the steering torque from the joystick input**
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 )))
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.
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)               
161 def acc_cb(self, data):
162 print("acc_cb: " + str(data))
163 **# setting the maximum and minimum value of the acceleration**
164 if > 1023:
165 self.acc_val = 1023
166 elif < -1023:
167 self.acc_val = -1023
168 self.acc_val =
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 > 3840:
174 self.steer_val = 3840
175 elif < -3840:
176 self.steer_val = -3840
177 self.steer_val =
178 )))
180 **Creation of CAN messages**
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:
185 (% class="box infomessage" %)
186 (((
187 def create_steer_command(packer, steer, steer_req, raw_cnt):         
189 """Creates a CAN message for the Toyota Steer Command."""
191 values = {
193 **# steering request can have 0 or 1 as value**
194 **~ **"STEER_REQUEST": steer_req,**      **
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 )))
205 (% class="wikigeneratedid" %)
206 The function //make_can_msg// uses another function called //pack_bytes//:
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 )))
216 (% class="wikigeneratedid" %)
217 The function //pack_bytes// appends the variables together using both the defined and built in //pack// functions:
219 (% class="box infomessage" %)
220 (((
221 def pack_bytes(self, addr, values, counter=-1):
222 addr, size = self.name_to_address_and_size[addr]
224 **# calling the pack function**
225 **~ **val = self.pack(addr, values, counter)
226 r = struct.pack(">Q", val)
227 return addr, r[:size]
228 )))
230 (% class="wikigeneratedid" %)
231 The //pack// function is defined as:
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] ="char[]", name)     
242 values_thing.append({
243 'name': self.sig_names[name],
244 'value': value
245 })
247 values_c ="SignalPackValue[]", values_thing)
249 return libdbc.canpack_pack(self.packer, addr, len(values_thing), values_c, counter)
250 )))
252 (% class="wikigeneratedid" %)
253 The package //libdbc// is defined as:
255 (% class="box infomessage" %)
256 (((
257 import os
258 import subprocess
260 from cffi import FFI
262 can_dir = os.path.dirname(os.path.abspath(~_~_file~_~_))
263 libdbc_fn = os.path.join(can_dir, "")
264 subprocess.check_call(["make"], cwd=can_dir)
266 ffi = FFI()
267 ffi.cdef()
269 libdbc = ffi.dlopen(libdbc_fn)
270 )))
272 **__Reading CAN messages from the CAN bus__**
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//.
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...")
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 = []
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.")
301 def can_cb(self, data):
302 self.to_send_msgs.append(data)
304 def run(self):
305 rate = rospy.Rate(self.rate)
306 while not rospy.is_shutdown():
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),# ... ]**
315 if can_msg_block:
316 self.process_msg_block(can_msg_block)
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 = []
323 **# sending all messages**
324 **~ **for msg in msgs:
325 self.send_can_msg(msg)
327 rate.sleep()
328 )))
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//.
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')
342 **# setting node as a publisher of messages in human friendly format**
344 **~ ** = rospy.Publisher('can_frame_msgs_human_friendly', String,queue_size=10)
346 **# setting node as a subscriber to CAN frame messages  **
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'] =
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] =
360 rospy.loginfo("To interpret the messages:")
361 pp = PrettyPrinter()
362 rospy.loginfo(pp.pformat(understood_msgs))
364 def _cb(self, data):
365 try:
366 msg = self.can_msg_parser.decode_message(,
367 msg['frame_id'] =
368 msg['message_name'] = self.msg_id_to_msg_name[]
369 msg['raw_msg'] = str(
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'] =
379 msg['message_name'] = "UNKNOWN_MESSAGE"
380 msg['raw_msg'] = str(
381 human_friendly = str(msg)
382 except ValueError:
383 msg = {}
384 msg['frame_id'] =
385 msg['message_name'] = "UNKNOWN_MESSAGE"
386 msg['raw_msg'] = str(
387 human_friendly = str(msg)
390 )))
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.
395 (% class="box infomessage" %)
396 (((
397 class TwistFromCan(object):
398 **# Constants**
403 def ~_~_init~_~_(self):
404 rospy.loginfo("Initializing TwistFromCan")
405 rp = RosPack()
406 pkg_path = rp.get_path('panda_bridge_ros')
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
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 **~ ** = rospy.Publisher("twist_stamped",TwistStamped, queue_size=10)
418 rospy.loginfo("Done")
420 def callback(self, msg):
421 msgID =
422 if (msgID == self.WHEEL_SPEED_MSG_ID):
423 data = self.can_db.decode_message(msgID,
424 speed_RL = data['WHEEL_SPEED_FL']
425 speed_RR = data['WHEEL_SPEED_FR']
426 self.wheel_speed = (speed_RL + speed_RR) / 2.0
428 if (msgID == self.KINEMATICS_MSG_ID):
429 data = self.can_db.decode_message(msgID,
430 self.yaw_rate = data['YAW_RATE']
431 )))
433 = **Modeling of a Supervisor for DbW System** =
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:
437 == //**Vehicle State**// ==
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.
441 [[image:image-20190415102656-1.png]]
443 **~ **// Automaton of Vehicle//
445 == //**System State**// ==
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.
449 [[image:image-20190415103149-2.png]]
451 // Automaton of DbW System//
453 == //**ON-OFF Button State**// ==
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.
457 [[image:image-20190415103149-3.png]]
459 **~ **//Automaton of ON-OFF Button//
461 == //**ROS State**// ==
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.
465 [[image:1555317194645-683.png]]
467 **~ **//Automaton of Ros//
469 == //**ECUs State**// ==
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.
473 [[image:image-20190415103312-5.png]]
475 **~ **// Automaton of ECU//
477 == //**Emergency (EM) Button State**// ==
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.
481 [[image:1555317291096-741.png]]
483 // Automaton of EM Button//
485 == //**Communication Channel State**// ==
487 The communication channel includes the hardware from (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.
489 [[image:1555317331714-290.png]]
491 **~ **//Automaton of Communication Channel//
493 == //**Supervisor**// ==
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.
497 (% class="wikigeneratedid" id="HRequirementsfortheactivationofDbWsystem" %)
498 //**Requirements for the activation of DbW system**//
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.**
504 (% class="wikigeneratedid" id="HRequirementsforthedeactivationofDbWsystem" %)
505 //**Requirements for the deactivation of DbW system**//
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.
511 (% class="wikigeneratedid" id="HRequirementfortheEmergencyStoporManualOverride" %)
512 //**Requirement for the Emergency Stop or Manual Override**//
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**.
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.
518 [[image:image-20190415103957-8.png]]
520 **~ **// Relationship between supervisor and modeled subsystems//
522 == //**Simulation**// ==
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.
526 [[image:1555317643701-278.png]]
528 **~ **// Simulation window with GUI input and state visualization//
530 == //**HMI**// ==
532 HMI is designed to observe the system state as shown in Figure 10.
534 [[image:image-20190415104111-10.jpeg]]
536 **~ **// HMI of DbW System in CIF 3.0 environment//
538 == **CIF Simulation Video** ==
540 {{video url="" attachment="CIF Simulation"/}}
542 = **Test Plan** =
544 == //**Overview**// ==
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.
548 == //**Test objectives**// ==
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:
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.
560 == //**Test cases**// ==
562 === //**Test case 1: Steering functionality**// ===
564 **Purpose:** To verify that the vehicle steers as desired by the operator through the joystick steering input.
566 **Test procedure:**
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.
572 **Expected result:** The steering sensor should feedback the same steering angle as commanded by the tester.
574 === //**Test case 2: Vehicle response time to steering command**// ===
576 **Purpose:** To verify that the latency between giving the steering input and the actual vehicle response is within the determined timeframe.
578 **Test procedure:**
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.
584 **Expected result:** The difference between inputting the steering command and the finish of actuation is within a TBD period.
586 === //**Test case 3: Acceleration functionality**// ===
588 **Purpose:** To verify that the vehicle accelerates as desired by the operator through the joystick acceleration input.
590 **Test procedure:**
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.
596 **Expected result:** The measured speeds should correspond with the input values
598 === //**Test 4: Vehicle response time to acceleration command**// ===
600 **Purpose:** To verify that the latency between giving the acceleration input and the actual vehicle response is within the determined timeframe.
602 **Test procedure:**
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.
608 **Expected result:** The difference between the input of the acceleration command and the vehicle starting to accelerate is within the TBD period.
610 === //**Test case 5: Steering and acceleration inter-operation test**// ===
612 **Purpose:** To verify that the vehicle steers and accelerates simultaneously as desired by the operator through the joystick steering and acceleration input.
614 **Test procedure:**
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.
621 **Expected result:** The steering sensor and speed sensor should give readings of the same entered steering angles and speeds.
623 === //**Test case 6: Brake functionality**// ===
625 **Purpose:** To verify that the vehicle brakes as desired by the operator through the joystick brake input.
627 **Test procedure:**
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.
634 **Expected result:** The vehicle should come from 30 km/h to a complete stop.
636 === //**Test case 7: Brakes response time**// ===
638 **Purpose: **To verify that the vehicle stops completely after receiving the command of maximum braking within TBD time.
640 **Test procedure:**
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.
649 **Expected result: **The vehicle starts decelerating after pressing the brake button within the TBD period.
651 === //**Test case 8: Emergency button functionality**// ===
653 **Purpose: **To verify that the vehicle is controlled by the driver once the emergency button is pressed.
655 **Test procedure:**
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.
663 **Expected result:** Vehicle control transfers to the driver; operator cannot control vehicle using joystick.
665 === //**Test case 9: Connection to CAN bus failure**// ===
667 **Purpose: **To verify that there will be warning in case of loss of information from the vehicle’s CAN bus.
669 Test procedure:
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.
676 **Expected result:** The HMI shows information loss warning once the bus is disconnected.
678 === //**Test case 10: Joystick failure**// ===
680 **Purpose:** To verify that the DbW system warns the operator and driver in case of the failure of the joystick.
682 **Test procedure:**
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.
689 **Expected result:** HMI shows warning signal of joystick failure once the joystick cable is unplugged.
691 === //**Test case 11: System activation and signaling (ON)**// ===
693 **Purpose: **To verify that the system will be activated and inform the driver and the operator about the status of the system (on).
695 **Test procedure:**
697 1. Activate the system.
698 1. Check the HMI for system status.
700 **Expected result:** once the system is activated, the HMI should signal that the system is on.
702 === //**Test case 12: System deactivation and signaling (Off)**// ===
704 **Purpose: **To verify that the system will be deactivated and inform the driver and the operator about the status of the system (off).
706 **Test procedure:**
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.
712 **Expected result**: Once the emergency button is pressed, HMI shows the system is off.
714 = **Conclusion and Recommendations** =
716 == //**Conclusion**// ==
718 The Drive-by-Wire functionality for Toyota Prius has been achieved using 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 A supervisor has also been implemented to incorporate the functional safety requirements and design the modes of operation for the system.
720 == //**Recommendations**// ==
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.
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 )))
737 = **Manual for operating the System** =
739 This manual gives the procedure required to setup all the ROS nodes for running the System.
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.
744 //Note: All the commands are entered in terminal.//
746 == **//Instructions for Reading CAN Messages//** ==
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.
758 * Type rosrun <package_name>
759 * Type rostopic echo /frame_messages to validate
761 * Run the node Frame_Decoder in terminal using rosrun <package_name>
762 * Type rostopic echo /human_friendly to validate
764 * Run the node can_listener_toyota in terminal using rosrun <package_name>
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.
773 This compiles all the packages in the SRC folder.
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.
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.
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 )))
789 == **//Instructions for Reading and Publishing Joystick Messages//** ==
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
798 * Type rosrun <package>
799 * Type rostopic echo /acceleartion to validate
801 * Type rosrun <package>
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:~~/~~/>>url:]].
809 The joy_to_acc node publishes the /acceleration topic by subscribing to the /joy topic.
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>
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 )))
823 (% class="col-xs-12 col-sm-4" %)
824 (((
825 (% class="box" %)
826 (((
827 = [[image:1554451298332-638.png]] =
829 |=Manufacturer|Toyota
830 |=Model|Prius
831 |=Year of manufacturing|2018
832 |=Image|[[Credits>>]]
833 )))
835 (% class="box" %)
836 (((
837 **Contents**
839 {{toc/}}
840 )))
841 )))
842 )))

Need help?

If you need help with XWiki you can contact:

MPS Group