38 Mơ hình chuồng trại bao gồm:
(1): Là tương ứng với Life Area trong mơ hình giả định, là khu vực sinh sống của đàn lợn
(2): Là khu vực cổng vào và có gắn một cái cân, tương ứng với WS Device trong mơ hình giả định. Cân chỉ hoạt động tương ứng với mỗi con lợn khi đến chu kì cân của nó (1 tuần cân 1 lần)
(3): Hệ thống máng ăn và nước uống gồm 5 máng, mỗi máng dành cho 1 con. Khi có con lợn nào đang ở trong máng thì những con lợn khác phải chọn máng khác.
(4): Cổng thoát khỏi khu vực ăn để trở về khu vực sống. Đồng thời trong lúc này, hệ thống máy tính sẽ ghi nhận lại lượng thức ăn mà lợn đã ăn trong ngày hơm đó.
Tiến hành mô phỏng: tiến hành với file Emulator.gaml
- Main_display: biểu thị màn hình khi mơ phỏng
- Info_display: biểu thị màn hình với những con lợn có ID của nó
- CFI_display: biểu thị biểu đồ đường cong CFI của từng con lợn
- Weight_display: biểu thị biểu đồ cân nặng của từng con lợn
- CFI_comparison: biểu đồ dạng cột biểu thị sự so sánh giữa các CFI
- Weight_display: biểu đồ dạng cột biểu thị sự so sánh giữa các cột cân nặng Các chức năng tích hợp sẵn trên giao diện GAMA:
Dừng chạy model Đồng bộ hóa dữ liệu
Lần lượt là phóng to, chiếu đến tầm nhìn hợp lí và thu nhỏ. Chụp màn hình lúc đang chạy model
Để chế độ tồn màn hình
Dùng để theo dõi một hay nhiều cá thể bất kì, có thể điều chỉnh thơng số một cách tùy ý cụ thể là như sau
39
Hình 3.11: Màn hình biểu thị thơng số của một cá thể đang được theo dõi
Hình 3.12: Các chức năng cơ bản khi theo dõi 1 cá thể
Khi nhấn vào “kill”, thì cá thể đang được theo dõi đó coi như là đã chết và dữ liệu ở các màn hình display sẽ giữ ngun, khơng thu thập thêm.Dưới đây là cài đặt và kết quả đầu ra của mơ phỏng máng ăn chính xác với quy mơ đàn lợn.
40
41
Hình 3.14: Thiết lập thơng số đầu ra của màn hình CFI_display
42
Hình 3.16: Giao diện màn hình Info_display
43
Hình 3.18: Đồ thị các cột CFI đã được trực quan hóa
44
Hình 3.20: Đồ thị các đường CFI qua từng ngày
Sau mỗi lần mô phỏng, hệ thống sẽ tự động ghi lại dữ liệu của từng cá thể lợn ở trong thư mực output. Ở đây hệ thống chia ra thành 2 thư mục nhỏ là real và simulation phục vụ lưu dữ liệu trong 2 trường hợp là mô phỏng với dữ liệu thật được truyền vào từ các file csv trong thư mục include và mô phỏng với dữ liệu mô phỏng do hệ thống tự tính tốn.
45
Hình 3.22: Các file kết quả đầu ra
Các file output dưới dạng csv ghi các dữ liệu đầu ra ứng với mỗi cá thể lợn sau mỗi lần mô phỏng.
46
Giá trị của file đầu ra ứng với giá trị thực tại số thời điểm dừng mô phỏng. Cột thứ 2 là trường “sex”, cột thứ 3 là “ID”, cột thứ 4 là “age”, cột thứ 5 là “DFI”, cột thứ 6 là “weight”, cột thứ 7 là “CFI”.
3.2. Xây dựng module BE 3.2.1. Bài toán: 3.2.1. Bài toán:
Mã nguồn ứng dụng GAMA hiện đã được xây dựng thành cơng như đã trình bày phía trên. Tuy nhiên bài tốn đặt ra khi người dùng, các cơ quan muốn sử dụng kết quả hay mô phỏng trên thì phải tải và cài đặt ứng dụng GAMA, kèm theo GAMA trong nhiều trường hợp lại không hỗ trợ tốt trên các nền tảng hệ điều hành như MacOS ( thử nghiệm với MacOS Big Sur) thì khơng thể mở phần mềm GAMA. Do đó tôi đã thiết kế ứng dụng điện toán đám mây dành cho việc chạy được các mã nguồn ứng dụng GAMA trên môi trường internet.
Ý tưởng: Sử dụng 1 máy chủ cài đặt GAMA platform. Mã nguồn mô phỏng máng lợn trên sẽ được người dùng tải từ website và được lưu trữ trên máy chủ cài đặt GAMA. Khi người dùng thao tác cũng như tiến hành thực hiện lệnh mô phỏng, hệ thống sẽ tự động kết nối đến máy chủ GAMA và tiến hành việc chạy mã nguồn ứng dụng như khi người dùng chạy trên môi trường desktop. Công việc được tiến hành qua cơ chế GAMA headless. Các dữ liệu như kết quả sau mô phỏng sẽ được xử lý và trả lại để hiển thị trên giao diện người dùng.
47
Hình 3.24: Mơ hình tổng quan hệ thống.
3.2.2. Headless Mode
Mục đích của tính năng này là có thể chạy một hoặc nhiều giao diện phiên bản của GAMA mà không cần bất kỳ giao diện người dùng nào, để các mơ hình và thử nghiệm có thể được khởi chạy trên lưới hoặc theo cụm. Nếu khơng có GUI, dung lượng bộ nhớ cũng như tốc độ mô phỏng thường được cải thiện đáng kể. Trong chế độ này, GAMA chỉ có thể được sử dụng để chạy thử nghiệm và khơng thể chỉnh sửa hoặc quản lý các mơ hình.
Có 2 cách để chạy thử nghiệm GAMA trong chế độ headless: sử dụng tập lệnh shell script chuyên dụng hoặc chạy trực tiếp từ dịng lệnh. Các tập lệnh này đều có 2 đối số: tệp thử nghiệm và đầu ra.
- Shell Script: Có thể được tìm thấy trong GAMA, tên là gamaHeadless.sh trên MacOSX và Linux hoặc gamaHeadless.bat trên Windows.
sh gamaHeadless $a $b Trong đó:
48
tệp thông số đầu vào $a: tệp xml xác định các thông số thử nghiệm và output
đường dẫn thư mục output $b: thư mục chứa kết quả mô phỏng
- Java Command:
java -cp $GAMA_CLASSPATH -Xms512m -Xmx2048m -
Djava.awt.headless=true org.eclipse.core.launcher.Main - application msi.gama.headless.id4 $1 $2
Trong đó:
tệp thơng số đầu vào $a: tệp xml xác định các thông số thử nghiệm và output
đường dẫn thư mục output $b: thư mục chứa kết quả mô phỏng
Experiment Input File (tệp đầu vào thử nghiệm): Tệp đầu vào xml có dạng như sau:
<?xml version="1.0" encoding="UTF-8"?> <Experiment_plan>
<Simulation id="2" sourcePath="./predatorPrey/predatorPrey.gaml" finalStep="1000" until="length(predator) = 1" experiment="predPrey"> <Parameters>
<Parameter name="nb_predator_init" type="INT" value="53" /> <Parameter name="nb_preys_init" type="INT" value="621" /> </Parameters>
<Outputs>
<Output id="1" name="main_display" framerate="10" /> <Output id="2" name="number_of_preys" framerate="1" /> <Output id="3" name="number_of_predators" framerate="1" /> <Output id="4" name="duration" framerate="1" />
</Outputs> </Simulation> </Experiment_plan>
- Heading:
<Simulation id="2" sourcePath="./predatorPrey/predatorPrey.gaml" finalStep="1000" until="length(predator) = 1" experiment="predPrey"> id: tạo tiền tố cho các tệp đầu ra thử nghiệm với các mô phỏng lớn
sourcePath: bao gồm đường dẫn tương đối hoặc tuyệt đối để đọc model gaml finalStep: xác định số bước mô phỏng muốn chạy.
until: xác định điều kiện dừng. Có thể kết hợp với finalStep
experiment: xác định thử nghiệm nào được chạy trên model. Thử nghiệm phải tồn tại, nếu không chế độ headless sẽ khơng được thốt.
- Parameter:
49
<Parameter name="nb_predator_init" type="INT" value="53" />
name: tên của tham số trong model gaml
type: kiểu dữ liệu của tham số (INT, FLOAT, BOOLEAN, STRING)
value: giá trị đã chọn - Outputs:
Mỗi dòng là của mỗi giá trị đầu ra mà ta muốn truy xuất. Đầu ra có thể là tên của monitor hoặc display đã được xác định trong phần output của thử nghiệm hoặc tên của thuộc tính được xác định trong thử nghiệm hoặc chính model.
... with the name of a monitor defined in the 'output' section of the
experiment...
<Output id="2" name="number_of_preys" framerate="1" />
... with the name of a (built-in) variable defined in the experiment itself...
<Output id="4" name="duration" framerate="1" /> Trong đó:
name: tên của outputr trong phần "output/permanent” hoặc tên thuộc tính experiment/model để truy xuất.
framerate: tần suất giám sát (ví dụ: mỗi 1 bước, mỗi 2 bước, mỗi 100 bước, …)
Lưu ý:
Giá trị tốc độ trên mỗi khung hình (framerate value) àng thấp, thì thử nghiệm càng dài
Nếu output đã chọn là display, một hình ảnh được hiện ra và file output chứa đường dẫn truy cập hình ảnh này.
- Output Directory: (Thư mục đầu ra)
Trong thử nghiệm headless, một thư mục sẽ được tạo ra và có cấu trúc như sau: Outputed-directory-path/ |-simulation-output.xml |- snapshot |- main_display2-0.png |- main_display2-10.png |- ... Trong đó:
simulation-output.xml: chứa những kết quả
snapshot: chứa các ảnh chụp nhanh trong q trình mơ phỏng - Simluation Output:
50 <?xml version="1.0" encoding="UTF-8"?> <Simulation id="2" >
<Step id='0' >
<Variable name='main_display' value='main_display2-0.png'/> <Variable name='number_of_preys' value='613'/>
<Variable name='number_of_predators' value='51'/> <Variable name='duration' value='6' />
</Step>
<Step id='1' >
<Variable name='main_display' value='main_display2-0.png'/> <Variable name='number_of_preys' value='624'/>
<Variable name='number_of_predators' value='51'/> <Variable name='duration' value='5' />
</Step>
<Step id='2'> Trong đó:
<Simulation id=”2”>: là chỗ chứa kết quả của mô phỏng thứ 2 (id = 2 được xác định trong Input Experiment File)
<Step id=’1> … </Step>: là chỗ thực hiện cho mỗi bước. Id sẽ tương ứng với mỗi bước.
- Step:
<Step id='1' >
<Variable name='main_display' value='main_display2-0.png'/> <Variable name='number_of_preys' value='624'/>
<Variable name='number_of_predators' value='51'/> <Variable name='duration' value='6' />
</Step>
Có một khối Variable với mỗi Ouput được xác định tỏng Output Experiment File.
- Variable:
<Variable name='main_display' value='main_display2-0.png'/> Trong đó:
name: là tên của output, biến model value: giá trị hiện tại của biến model
Lưu ý rằng giá trị của outpt được lặp lại dựa vào framerate được xác định trong Input Experiment File.
- Snapshot files:
Chứa các hình ảnh đầu ra được tạo ra trong q trình chạy thử nghiệm. Có một hình ảnh trên mỗi output hiện thị trên mỗi bước. Tên file tuân theo quy tắc đặt tên, ví dụ:
51
Hình ảnh sẽ được lưu dưới định dạng mở rộng “.png”
3.2.3. Cấu hình dự án backend:
Tiến hành cấu hình dự án [13] với docker, tơi sử dụng 4 container.
Cấu hình tệp docker-compose.yml: docker compose là công cụ dùng để định
nghĩa và chạy nhiều container, mỗi container là 1 dịch vụ mình cài đặt để ứng dụng có thể hoạt động bình thường. Tơi sử dụng file YAML để cấu hình cho từng dịch vụ. Cụ thể chúng tôi sử dụng 4 dịch vụ: nginx, php, mysql, redis.
Nginx: Là open source để phục vụ web, reverse proxying, caching, load
balancing, media streaming... Nó bắt đầu như một máy chủ web được thiết kế để có hiệu suất và sự ổn định tối đa. Ngồi các khả năng của máy chủ HTTP, Nginx cũng có thể hoạt động như một máy chủ proxy cho email (IMAP, POP3, SMTP) và một trình cân bằng tải và proxy ngược cho các máy chủ HTTP, TCP, UDP.
Ưu điểm:
- Cung cấp khả năng xử lý nhiều yêu cầu (hơn 10.000 kết nối) cùng lúc với yêu cầu bộ nhớ thấp.
- Phục vụ tập tin tĩnh (static files) và lập chỉ mục tập tin.
- Tăng tốc reverse proxy bằng bộ nhớ đệm (cache), kèm theo cân bằng tải và khả năng chịu lỗi.
- Giúp tăng tốc với bộ nhớ đệm dựa trên FastCGI, uwsgi, SCGI, và các máy chủ memcached.
- Kiến trúc mô đun, tăng tốc độ nạp trang bằng nén gzip tự động.
- Hỗ trợ các chuẩn mã hoá hiện đại và an toàn nhất hiện nay như SSL và TLS. - Cấu hình linh hoạt, lưu trữ lại nhật ký truy vấn.
- Chuyển hướng lỗi 3XX-5XX
- Rewrite URL (URL rewriting) dùng regular expressions
- Cung cấp cơ chế chống tấn công từ chối dịch vụ thông qua giới hạn số kết nối đồng thời hoặc truy vấn cùng từ 1 địa chỉ
- Khả năng nhúng mã PERL
PHP: Ở đây chúng tôi thiết lập môi trường làm việc của php trong container. Do
52
thiết phải cài đặt môi trường để tập mã nguồn dự án có thể biên dịch và thực thi trên máy. Đặc điểm của PHP hay chính xác hơn là Laravel đã được trình bày ở trên.
Mysql: MySQL là một hệ thống quản trị cơ sở dữ liệu mã nguồn mở (Relational
Database Management System, viết tắt là RDBMS) hoạt động theo mơ hình máy khách - máy chủ. Đặc điểm của MySQL cũng đã được trình bày ở trên.
Redis: Redis là một open-source cho phép chúng ta có thể lưu trữ data trong
memory. Người dùng có thể sử dụng Redis để làm database, caching hoặc message broker
Ngồi tính năng lưu trữ KEY-VALUE trên RAM thì Redis cịn hỗ trợ tính năng sắp xếp, query, backup dữ liệu trên đĩa cứng cho phép bạn có thể phục hồi dữ liệu khi hệ thống gặp sự cố…và có thể nhân bản (Chạy nhiều Server Redis cùng lúc).
- Caching: Sử dụng làm bộ nhớ đệm. Chính tốc độ đọc ghi nhanh mà Redis có thể làm bộ nhớ đệm, nơi chia sẻ dữ liệu giữa các ứng dụng hoặc làm database tạm thời. Ngồi ra Redis có thể sử dụng để làm Full Page Cache cho website. Cũng vì tính nhất quán của Redis, cho dù restart Redis thì người dùng cũng khơng có cảm nhận chậm khi tải trang.
- Counter: Sử dụng làm bộ đếm. Với thuộc tính tăng giảm thơng số rất nhanh trong khi dữ liệu được lưu trên RAM, sets và sorted sets được sử dụng thực hiện đếm lượt view của một website, các bảng xếp hạng trong game chẳng hạn. Redis hỗ trợ thread safe do đó nó có thể đồng bộ dữ liệu giữa các request.
- Publish/Subscribe (Pub/Sub): Tạo kênh chia sẻ dữ liệu. Redis hỗ trợ tạo các channel để trao đổi dữ liệu giữa publisher và subscriber giống như channel trong Socket Cluster hay topic trong Apache Kafka. Ví dụ: Pub/Sub được sử dụng theo dõi các kết nối trong mạng xã hội hoặc các hệ thống chat.
- Queues: Tạo hàng đợi để xử lý lần lượt các request. Redis cho phép lưu trữ theo list và cung cấp rất nhiều thao tác với các phần tử trong list, vì vậy nó cịn được sử dụng như một message queue.
FROM php:7.4-fpm
# Set working directory
WORKDIR /var/www
53
RUN apt-get update && apt-get install -y build-essential libpng-dev libjpeg62-turbo-dev libfreetype6-dev locales jpegoptim optipng pngquant gifsicle libzip-dev zip ffmpeg
# Install extensions
RUN docker-php-ext-install pdo_mysql RUN docker-php-ext-install gd
RUN apt-get install libsodium-dev -y RUN docker-php-ext-install sodium RUN docker-php-ext-install exif RUN docker-php-ext-install zip
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install- dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www/
# Copy existing application directory permissions
COPY --chown=www:www . /var/www/
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000 CMD ["php-fpm"] Đoạn mã 3.1: Dockerfile //docker-compose.yml version: '3' services: nginx: image: nginx:stable container_name: gama_nginx restart: always ports: - "8080:80" - "443:443" volumes: - ./:/var/www - ./docker/config/nginx.conf:/etc/nginx/nginx.conf - ./docker/config/app.conf:/etc/nginx/conf.d/default.conf
54 depends_on: - php networks: - app-network php: build: context: . dockerfile: ./docker/DockerFile restart: always container_name: gama_php volumes: - "./:/var/www" - ./docker/php_config/php.ini:/usr/local/etc/php/php.ini ports: - "9000:9000" networks: - app-network mysql: image: mysql:8.0 container_name: gama_db restart: always ports: - "3306:3306" volumes: - my-datavolume:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: ${DB_DATABASE} MYSQL_USER: ${DB_USERNAME} MYSQL_PASSWORD: ${DB_PASSWORD} networks: - app-network redis: image: redis:latest container_name: gama_redis restart: always ports: - "6379:6379" networks: - app-network networks: app-network: driver: bridge volumes: my-datavolume: Đoạn mã 3.2: docker-compose.yml
55
Sau khi cấu hình thì sản phẩm sẽ chạy với 4 container như sau:
Hình 3.25: Các container ở chế độ đang chạy
3.2.4: Thiết kế cơ sở dữ liệu