2020/10/29

hybrid : ISG : integrated Starter and Generator

先是 SUZUKI 說會出一款 hybrid,低價。
去看一下,基本沒什麼不同。
就是 以前 starter 的位置,變成一個 ISG
這個 ISG 就是 啟動器和發電機 一體。

因為 starter 連著傳動軸,所以也可以用來提供動力。
也因為連著傳動軸,所以也可以用來發電。

然後這種 hybrid 就是...
放開油門或是採煞車時,進入發電機模式,發出來的電,用來充鋰電池。
需要額外動力 (加速),或是啟動的時候,進入starter mode,利用鋰電池的電能,轉動 starter,提供動力。

這個 ISG 的位置,好像在離合器的地方,所以大部分目前的汽油車都可以改成這樣。
車上有兩顆電池,一個是以往的鉛酸電池,供發動汽油和一般(冷氣,大燈...etc)用。
另一棵是鋰電池。供 ISG 回充或是提供動力用。

原來依照使用電力的階段,可以分為 Micro. Mild,Full, Plugin (ref)

然後依照 ISG 與動力連接的方式,分為兩種: CiSG (crankshaft-integrated motor generator) 和 BiSG (belt-integrated starter generato)


依照這一篇(中文) 的說明,hybrid 的介入分類,是以ISG 能提供的動力來分類,同時,能提供的動力越多,ISG 的電壓也越高。

這一篇 有畫出 CiBG 與 cranshift 的關係,因為在引擎跟變速箱之間,有兩個離合器,所以可以隔離引擎。
ref:

2020/10/27

Boost asio http request, test with served

served 的 example : handler,有印出 post request 的 body..
    // GET or POST /handlers/{id}/{number:[0-9]+}
    mux.handle("/handlers/{id}/{number:[0-9]+}")

        .post([](served::response & res, const served::request & req) {
            res << "id: ";
            res << req.params["id"];
            res << ", number: ";
            res << req.params["number"];

            std::cout << "POST: " << req.body() << std::endl;
        })
先用 curl 測試一下...
參考這個,依照上面的 url path 修改一下...
curl -X POST -H "Content-Type: text/plain" --data "this is raw data" http123/handlers/id/123
結果 served example : eg_handler 正確送出:
$ ./eg_handlers 
Try this example with:
 curl http://localhost:8123/handlers
 curl http://localhost:8123/handlers/test
 curl http://localhost:8123/handlers/test/10
 curl http://localhost:8123/handlers/test/NaN
POST: this is raw data

對應的 tcp stream code:
#include <boost/asio.hpp>

int main()
{
	boost::asio::ip::tcp::iostream s("127.0.0.1","8123");
	s << "POST /handlers/test/10 HTTP/1.1\r\n";
	s << "Host: 127.0.0.1\r\n";
	s << "Content-Type: text/plain\r\n";
	s << "Content-length: 2\r\n";
	s << "\r\n";
	s << "bb\n";
	s << "\r\n";
}
使用上面修改過的 eg_handler 作為 REST server。可以正確..
Try this example with:
 curl http://localhost:8123/handlers
 curl http://localhost:8123/handlers/test
 curl http://localhost:8123/handlers/test/10
 curl http://localhost:8123/handlers/test/NaN
POST: bb
收到 body : bb

測試 PUT 命令:
用 served example : reset_resource,修改,印出body 和 parameter
   mux.handle("/customers/{id}")
        .get([](served::response & res, const served::request & req) {
            (void) res;
            (void) req;
            // read customer req.params["id"]
            std::cout << "get" << std::endl;
        })
        .put([](served::response & res, const served::request & req) {
            (void) res;
            (void) req;
            // update customer req.params["id"]
            std::cout << "put" + req.params["id"] << std::endl;
            std::cout << "header" << req.header("Content-Length") << std::endl;
            std::cout << "version" << req.HTTP_version() << std::endl;
            std::cout << req.body() << std::endl;
        })
對應使用 asio tcp stream 的 client code:
#include <boost/asio.hpp>

int main()
{
	boost::asio::ip::tcp::iostream s("127.0.0.1","8123");
	s << "PUT /customers/abc HTTP/1.1\r\n";
	s << "Host: 127.0.0.1\r\n";
	s << "Content-Type: text/plain\r\n";
	s << "Content-length: 2\r\n";
	s << "\r\n";
	s << "bb\n";
	s << "\r\n";
}
-- 其實跟 post 一樣…只是 url path 跟 request cmd 不一樣。
節果 eg_reset_resource 一樣正確取得 parameter 跟 body
putabc
header2
versionHTTP/1.1
bb

HOST: 可以不送。
重點是 content-type,沒有這個 key 得話,收不到 body
還有每一行都要是 \r\n 結尾,不可以只用 \n


有關 RESETful client server 的 debug..
client 可以用 curl 和 postman 來發送標準的 http request
然後用 whireshark log HTTP 來比對自己寫的 client 和 postman 送的有什麼不同。

順便記一下,httpie 是 command line 的 http api client, opensource 的
-- 其實或許跟 curl 一樣。

served 的 example,如果要對所有 nic interface 都listen 的話,就用 "0.0.0.0"
這樣舊可以用外部測試了。
-- ref:boost asio tcp server bind to any

programming with Boost library,

在 ubuntu 系統中使用 boost library
首先要安裝 boost dev library: libboost-all-dev

然後分為:

只有用到 boost 的 header: boostlambda.cpp
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>

int main()
{
    using namespace boost::lambda;
    typedef std::istream_iterator<int> in;

    std::for_each(
        in(std::cin), in(), std::cout << (_1 * 3) << " " );
}
這樣build command 就不用特別加什麼:
g++ boostlambda.cpp

如果包含 library,以這個例子,用到 boost_regex : boostregex.cpp
#include <boost/regex.hpp>
#include <iostream>
#include <string>

int main()
{
    std::string line;
    boost::regex pat( "^Subject: (Re: |Aw: )*(.*)" );

    while (std::cin)
    {
        std::getline(std::cin, line);
        boost::smatch matches;
        if (boost::regex_match(line, matches, pat))
            std::cout << matches[2] << std::endl;
    }
}
這樣 build command 就要加上 boost library
g++ boostregex.cpp -lboost_regex



如果是要 cross build for embedded.列如 for arm.
先 cross build boost library,假設build 好都放在 /dm1lib/ (include & lib)

compiple 就只要指定 additional include path (-I)和 additional libary path (-L)就可以...
aarch64-linux-gnu-g++ fexist.cpp -I/dm1lib/include -lboost_system -lboost_filesystem -L/dm1lib/lib

http PUT request

最清楚簡單的 example 在 這裡
還有這一篇 有詳細的 example 和 server response 的解釋。

這一篇 有說,如何用 curl 下 PUT request

使用 Boost asio 來發。這篇 的回答有比較詳細的(但是是 POST request),可以參考。
這一個 pdf 中也有 tcp stream 的寫法:
tcp::iostream s("www.boost.org", "http");

s.expires_from_now(std::chrono::seconds(60));

s << "GET / HTTP/1.0\r0.2cm\n";
s << "Host: www.boost.org\r\n";
s << "Accept: */*\r\n";
s << "Connection: close\r\n\r\n";
And then receive and process the response:
std::string header;
while (std::getline(s, header) && header != "\r")
 std::cout << header << "\n";
std::cout << s.rdbuf();
If at any time there is an error, the tcp::iostream class’s error() member function may be used to determine the reason for failure:
if (!s)
{
 std::cout << "Socket error: " << s.error().message() << "\n";
 return 1;
}

所以用 boost::asio 來寫一個 PUT request: boostasio.cpp
#include <boost/asio.hpp>

int main()
{
	boost::asio::ip::tcp::iostream s("127.0.0.1","8123");
	s << "PUT /customers/23 HTTP/1.1\n";
	s << "Host: 127.0.0.1\r\n";
	s << "Content-length: 0\r\n";
	s << "\r\n";
//	s << std::flush;
}
build command:
g++ boostasio.cpp -lboost_system -lpthread

配合 json 作為 PUT 的 body 要參考這裡:
PUT /echo/put/json HTTP/1.1
Accept: application/json
Content-Type: application/json
Content-Length: 85
Host: reqbin.com

{
  "Id": 12345,
  "Customer": "John Smith",
  "Quantity": 1,
  "Price": 10.00
}

如果要看 server 的 reponse,這一篇 有簡單的 example,
就是..
ip::tcp::iostream stream;
stream.expires_from_now(boost::posix_time::seconds(60));
stream.connect("www.boost.org", "http");
stream << "GET /LICENSE_1_0.txt HTTP/1.0\r\n";
stream << "Host: www.boost.org\r\n";
stream << "Accept: */*\r\n";
stream << "Connection: close\r\n\r\n";
stream.flush();
std::cout << stream.rdbuf();

RESTful Client Library in C++


restc-cpp

  • 使用 Boost
  • 支援https
  • 支援 Json
看example,寫起來簡單漂亮。
make 是用 cmake


webcc

  • 使用Boost Asio
  • 支援 https
  • 支援json
  • 有 client 跟 server
看 example,有很多,
寫起來稍微比 restc-cpp 需要多一些 code

感覺功能比較多,還有keep-alive, file-download/upload ..等等功能
一樣用 cmake


Unbuffered socket iostreams

就是直接用 Boost.Asio 的 tcp::iostream 來操作。

感覺很厲害,,,就是 hard-coding http request....

2020/10/20

follow 安裝 add-apt-reposity
add-apt-repository 後,follow 這一篇 把 pgp key 加近來

原來是locale 的關係。
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php
指定 encode 就可以。


然後就是 apt install phabricator
會裝 apache2 跟 mysql 跟 php...
還有
apt install python-software-properties software-properties-common 
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej
apt update
apt upgrade

apt-get install git nginx mysql-server
要輸入 mysql 的 root password

2020/10/19

dell inspiron

LXDE 改用,Qt 了!? 而memory 沒有多很多,那就來試試看吧,剛好上次修NB 的 win10竟然到期了!
安裝 lts (20.04) 好了。

wifi 竟然部會洞..
lspci 看一下是 bcm4313, 參考這一個,安裝 package firmware-b43legacy-installer ,再裝 linux-firmware,之後 reboot 在 右下network 舊可以選了。

chewing (酷音)安裝:
apt install fcitx fcitx-chewing
裝完之後,要重新開機,在 fcitx configuration 就可以看到 chewing 輸入法了。
-- fcitx 的chewing可以調整的地方不多,像不能用shift快速換中英輸入。只能固定用左邊shift key

miniconda
其實就是download...
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
然後run 就可以。



2024-01-21 update

因為GLIBC 不夠新。所以加上 2024 (jammy) 到 sources.list,安裝後 break distribution package。
所以想乾脆更新好了,所以用 upgrade 而不是重新安裝。
在 /etc/update-manager 下有一個 do-dist-release,就 run 這個 script 就可以。
無痛安裝完畢,之後開啟 additional driver,wifi default 就 OK 了,另外選擇安裝propriety STA driver 也 OK

totolink 的 usb-wifi,安裝完 usb-modeswitch 之後, /lib/udev/rules.d/ 下就會有 40-usb_modeswitch.rules,follow 以前那篇,加上 totolink 的 rules 後,reboot,插入 usb-wifi,就自動啟動了,不用再自己拉 driver source 下來 build.


2024/02/24 update

更新後重開機,wifi 就打不開了。
用 rfkill 看,wlan 是 hardware blocked
代表網卡開關是關掉的,這個要用 bios hotkey 來開關,通常在 windows 才支援。
所以只好去bios 把所有rf (bt, wlan, wwan) 的support 改成 None,然後把default 都 enable。
開啟 ubuntu,wifi 就不是hardware blocked,也可以開了。

另外在安裝注音時,出現問題。

順序應該是:
在 language\Location 中安裝Chinese(Tranditional)
然後要重開機。
然後 install ibus-chewing,有時候已經安裝了。
之後reboot
去 "設定" -- Keyboard
加入 Chinese(Chewing),要去下面 ... 那格,之後選 Other 才會出現。

2020/10/16

/etc/fstab and systemd-fsck

systemctl status rc-local.service
systemd-fsck 是用來自動 fsck 的 daemon(?),分為兩個:
  • systemd-fsck.root.service : 負責對 root filesystem 做 fsck
  • systemd-fsck@.service : 負責對其他(非 root) 的 filesystem 做 fsck
他會根據 /etc/fstab 的內容,決定哪些 partition 需要檢查。
就是 fstab 中最後一個 field : pass
  • 0: 不檢查
  • 1: root用,要檢查
  • 2: 其他 parttition,要檢查
他會call fsck.XXX (XXX = filesystem type) 來做 fsck,所以要有對應的 fsck tool


另外,fsck (沒有.XXX) 會依照 /etc/fstab 的內容,自動 call 對應的 fsck.XXX 對 pass 不是 0 的 partition 檢查。

2020/10/13

bookmark : ADAS 的鬼影 和 魔鬼剋星

這一篇 用投影的方式欺騙 影像形式 的 ADAS 系統。
從影片看來非常有效..

這就像以前說的,單鏡頭無法分辨 3D 投影圖案是真的還是假的。
另外,用內嵌影像在影片中的方式,讓人眼沒感覺 (1/30 sec),但是 ADAS 鏡頭偵測得到。
還有投影路標線到道路上 (這個台灣舊一堆道路分隔現是亂七八糟的),讓 ADAS 誤判。

文章用 Ghost 來形容這些欺騙 ADAS 的物體。

然後。最後,他用一個model 來偵測這些 Ghost,network 就叫 GhostBuster...

... 但是他只有說有效,沒有示範影片。

我是覺得連人都會誤判的,要叫 Video type ADAS 系統分辨出來,是有點難了些...
而且誤判物件而停車減速。總比未偵測到而撞上來好得多...(像那個有名的貨櫃車翻車影像)


另外 這一篇 就是,..burger king 的廣告招牌讓 ADAS 誤判而慢下來...
-- 達到廣告效果 ?

可見以後 Video Type ADAS 系統普及後,會有更多利用他的廣告作法...

2020/10/12

nginx as a https reverse proxy to served test program and enable basic authentication

served 沒有 support https,所以用 nigx 做 reverse proxy,將 https 轉成 http 給 served.

served 部份就用 example 來測試。所以重點就是 nginx 左為一個 https reverese proxy 的設定..
  • 啟動 https
  • 將 https 轉為 http ,送到 served。(reverse proxy)
  • 啟動 basic authentication, 要求登入

nginx 要啟動 https,要先有 ssl 憑證。
因為是local 測試用,所以就自己產生一個就好。

ref 的網站說明一樣,用 openssl 產生:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
其中 common name (FQDN) 就用 ip address : 172.16.200.11 這樣就可以。

產生 test.crt, test.key 兩個檔。放到 /etc/nginx/ssl/ 下。

然後修改 /etc/nginx/sites-available/default
加入:
       listen 443 ssl default_server;
       listen [::]:443 ssl default_server;

       ssl_certificate /etc/nginx/ssl/test.crt;
       ssl_certificate_key /etc/nginx/ssl/test.key;
重新啟動,測試一下,應該能看到 nginx 的 welcome page

reverse proxy 部份好像不分 https 還是 http,一樣是在 location 區塊加上
       proxy_pass http://localhost:8123/;
這樣舊可以。

啟動 served 的 example...
/served/bin$ ./eg_hello_world
Try this example with:
 curl http://localhost:8123/hello
這樣在其他機器上用 https://172.16.200.11/hello 舊可以看到 ...

最後就是啟動 basic authentication

需要有 user:password 檔。
簡單的方法是用 apache2-utils 的 htpasswd 產生。
但是在 embedd system 要 cross-build htpasswd 很麻煩,就用 openssl 來產生。
-- openssl 在啟動 openssl-server 時會一起build

這裡提供了一堆產生 password 的方法。都不用 apache2-utils 的 htpasswd

這裡用一般的,openssl passwd 的方法:
sudo sh -c "echo -n 'sammy:' >> /etc/nginx/.htpasswd"
sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd"
* password 好像要6 個 character,用 1234 個的話每次都會 login fail

這樣舊產生好 user: sammy 的 password 。
然後在 nginx 的 location 區段加上
        auth_basic "Restricted Content";
        auth_basic_user_file /etc/nginx/.htpasswd;
重新啟動 nginx 後,在 https://172.16.200.11/hello 就會跳出login 對話盒,輸入username, password 就會出現 served 的 hello world 字樣。


設定完後,可以用 openssl 來看你的 CA chain 和 TLS version....
$ openssl s_client -connect www.godaddy.com:443
...
Certificate chain
 0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US
     /1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc
     /OU=MIS Department/CN=www.GoDaddy.com
     /serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b)
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
 2 s:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc.
     /OU=ValiCert Class 2 Policy Validat$ openssl s_client -connect www.godaddy.com:443
...
Certificate chain
 0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US
     /1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc
     /OU=MIS Department/CN=www.GoDaddy.com
     /serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b)
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
 2 s:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc.
     /OU=ValiCert Class 2 Policy Validation Authority
     /CN=http://www.valicert.com//emailAddress=info@valicert.comion Authority
     /CN=http://www.valicert.com//emailAddress=info@valicert.com

2020/10/8

Makefile for building served liked program

要使用cross build 好的 served library 的話,要指定 boost library 和 served lib/include path。

先找出 CMake build example 的 build command..

把CMakeLists.txt 的 VERBOSE 打開。make 一次,然後 touch hello_world/main.cpp 再 make 一次。找出 make command:
/usr/local/linaro-aarch64-2018.08-gcc8.2/bin/aarch64-linux-gnu-g++   
-I/home/charles-chang/githubgitlab/served/src 
-I/tmp/boost/include  
-std=c++11 -Wall -pedantic -Wextra -Wno-missing-field-initializers   
-o CMakeFiles/eg_hello_world.dir/main.cpp.o 
-c /home/charles-chang/githubgitlab/served/src/examples/hello_world/main.cpp



/usr/local/linaro-aarch64-2018.08-gcc8.2/bin/aarch64-linux-gnu-g++   
-std=c++11 -Wall -pedantic -Wextra -Wno-missing-field-initializers  -rdynamic 
CMakeFiles/eg_hello_world.dir/main.cpp.o  
-o /home/charles-chang/githubgitlab/served/bin/eg_hello_world  
-L/tmp/boost/lib 
-Wl,-rpath,/tmp/boost/lib:/home/charles-chang/githubgitlab/served/lib: /home/charles-chang/githubgitlab/served/lib/libserved.so.1.4 /tmp/boost/lib/libboost_system.so 
-lpthread 
分別是 compile 和 link

所以 Makefile...
CC=aarch64-linux-gnu-g++
CFLAGS=-I/home/charles-chang/githubgitlab/served/src -I/tmp/boost/include -std=c++11 -Wall -pedantic -Wextra -Wno-missing-field-initializers
LDFLAGS=-std=c++11 -Wall -pedantic -Wextra -Wno-missing-field-initializers -rdynamic
LLIBS=-L/tmp/boost/lib -Wl,-rpath,/tmp/boost/lib:/home/charles-chang/githubgitlab/served/lib: /home/charles-chang/githubgitlab/served/lib/libserved.so.1.4 /tmp/boost/lib/libboost_system.so -lpthread


%.o: %.cpp
    $(CC) $(CFLAGS) -c -o $@ $< 


hello_world: main.o
    $(CC) $(LDFLAGS) -o $@ $^ $(LLIBS)