1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef CONFIG_MANAGER_H
17 #define CONFIG_MANAGER_H
18 
19 #include <cerrno>
20 #include <string>
21 #include <vector>
22 
23 #include <system/graphics-base.h>
24 
25 class ConfigManager final {
26 public:
27     struct CameraInfo {
28         std::string cameraId = "";  // The name of the camera from the point of view of the HAL
29         std::string function = "";  // The expected use for this camera ("reverse", "left", "right")
30         float position[3] = {0};    // x, y, z -> right, fwd, up in the units of car space
31         float yaw = 0;       // radians positive to the left (right hand rule about global z axis)
32         float pitch = 0;     // positive upward (ie: right hand rule about local x axis)
33         float roll = 0;      // radians positively increasing clockwisely around the optical axis
34         float hfov = 0;      // radians
35         float vfov = 0;      // radians
36         bool hflip = false;  // boolean to flip the preview horizontally
37         bool vflip = false;  // boolean to flip the preview vertically
38     };
39 
40     struct DisplayInfo {
41         uint8_t port = 0;            // Display port number to use
42         std::string function = "";   // The expected use for this display.
43         float frontRangeInCarSpace;  // How far the display extends in front of the car
44         float rearRangeInCarSpace;   // How far the display extends behind the car
45     };
46 
47     bool initialize(const char* configFileName);
48 
49     // World space dimensions of the car
getCarWidth()50     float getCarWidth() const { return mCarWidth; };
getCarLength()51     float getCarLength() const { return mWheelBase + mFrontExtent + mRearExtent; };
getWheelBase()52     float getWheelBase() const { return mWheelBase; };
53 
54     // Car space (world space centered on the rear axel) edges of the car
getFrontLocation()55     float getFrontLocation() const { return mWheelBase + mFrontExtent; };
getRearLocation()56     float getRearLocation() const { return -mRearExtent; };
getRightLocation()57     float getRightLocation() const { return mCarWidth * 0.5f; };
getLeftLocation()58     float getLeftLocation() const { return -mCarWidth * 0.5f; };
59 
60     // Where are the edges of the top down display in car space?
getDisplayTopLocation()61     float getDisplayTopLocation() const {
62         // From the rear axel (origin) to the front bumper, and then beyond by the front range
63         return mWheelBase + mFrontExtent + mDisplays[mActiveDisplayId].frontRangeInCarSpace;
64     };
getDisplayBottomLocation()65     float getDisplayBottomLocation() const {
66         // From the rear axel (origin) to the back bumper, and then beyond by the back range
67         return -mRearExtent - mDisplays[mActiveDisplayId].rearRangeInCarSpace;
68     };
getDisplayRightLocation(float aspectRatio)69     float getDisplayRightLocation(float aspectRatio) const {
70         // Given the display aspect ratio (width over height), how far can we see to the right?
71         return (getDisplayTopLocation() - getDisplayBottomLocation()) * 0.5f * aspectRatio;
72     };
getDisplayLeftLocation(float aspectRatio)73     float getDisplayLeftLocation(float aspectRatio) const {
74         // Given the display aspect ratio (width over height), how far can we see to the left?
75         return -getDisplayRightLocation(aspectRatio);
76     };
77 
78     // At which texel (vertically in the image) are the front and rear bumpers of the car?
carGraphicFrontPixel()79     float carGraphicFrontPixel() const { return mCarGraphicFrontPixel; };
carGraphicRearPixel()80     float carGraphicRearPixel() const { return mCarGraphicRearPixel; };
81 
getCameras()82     const std::vector<CameraInfo>& getCameras() const { return mCameras; };
83 
setActiveDisplayId(int displayId)84     int setActiveDisplayId(int displayId) {
85         if (displayId == -1) {
86             // -1 is reserved for the default display, which is the first
87             // display in config.json's display list
88             printf("Uses a display with id %d", mDisplays[0].port);
89             mActiveDisplayId = mDisplays[0].port;
90             return mActiveDisplayId;
91         } else if (displayId < 0) {
92             printf("Display %d is invalid.", displayId);
93             return -ENOENT;
94         } else {
95             for (auto display : mDisplays) {
96                 if (display.port == displayId) {
97                     mActiveDisplayId = displayId;
98                     return mActiveDisplayId;
99                 }
100             }
101 
102             printf("Display %d does not exist.", displayId);
103             return -ENOENT;
104         }
105     }
getDisplays()106     const std::vector<DisplayInfo>& getDisplays() const { return mDisplays; };
getActiveDisplay()107     const DisplayInfo& getActiveDisplay() const { return mDisplays[mActiveDisplayId]; };
useExternalMemory(bool flag)108     void useExternalMemory(bool flag) { mUseExternalMemory = flag; }
getUseExternalMemory()109     bool getUseExternalMemory() const { return mUseExternalMemory; }
setExternalMemoryFormat(android_pixel_format_t format)110     void setExternalMemoryFormat(android_pixel_format_t format) { mExternalMemoryFormat = format; }
getExternalMemoryFormat()111     android_pixel_format_t getExternalMemoryFormat() const { return mExternalMemoryFormat; }
setMockGearSignal(int32_t signal)112     void setMockGearSignal(int32_t signal) { mMockGearSignal = signal; }
getMockGearSignal()113     int32_t getMockGearSignal() const { return mMockGearSignal; }
114 
115 private:
116     // Camera information
117     std::vector<CameraInfo> mCameras;
118 
119     // Display information
120     std::vector<DisplayInfo> mDisplays;
121     int mActiveDisplayId;
122 
123     // Memory management
124     bool mUseExternalMemory;
125 
126     // Format of external memory
127     android_pixel_format_t mExternalMemoryFormat;
128 
129     // Gear signal to simulate in test mode
130     int32_t mMockGearSignal;
131 
132     // Car body information (assumes front wheel steering and origin at center of rear axel)
133     // Note that units aren't specified and don't matter as long as all length units are consistent
134     // within the JSON file from which we parse.  That is, if everything is in meters, that's fine.
135     // Everything in mm?  That's fine too.
136     float mCarWidth;
137     float mWheelBase;
138     float mFrontExtent;
139     float mRearExtent;
140 
141     // Top view car image information
142     float mCarGraphicFrontPixel;  // How many pixels from the top of the image does the car start
143     float mCarGraphicRearPixel;   // How many pixels from the top of the image does the car end
144 };
145 
146 #endif  // CONFIG_MANAGER_H
147